home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / util / misc / ReportPlus.lha / reportplus / source / f6.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-06-25  |  84.1 KB  |  2,163 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <intuition/gadgetclass.h>
  5. #include <libraries/gadtools.h>
  6. #include <libraries/iffparse.h>
  7. #include <graphics/gfx.h>
  8. #include <dos/dos.h>
  9. #include <dos/datetime.h>
  10.  
  11. #include <clib/alib_protos.h>
  12. #include <clib/exec_protos.h>
  13. #include <clib/intuition_protos.h>
  14. #include <clib/gadtools_protos.h>
  15. #include <clib/iffparse_protos.h>
  16. #include <clib/dos_protos.h>
  17. #include <clib/graphics_protos.h>
  18.  
  19. #include <ctype.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "rp.h"
  23.  
  24. #define CHUNKS 35
  25. // Variable-length blocks, and/or blocks that we read entirely, are
  26. // represented as chunksize = 0 and fixed = FALSE.
  27. struct
  28. {   TEXT   formname[5], chunkname[5];
  29.     ULONG  bytes;
  30.     ABOOL  fixed;
  31. } chunks[CHUNKS + 1] =
  32. { {"    ", "(c) ",  0, FALSE}, // "    " means any
  33.   {"    ", "ANNO",  0, FALSE},
  34.   {"    ", "AUTH",  0, FALSE},
  35.   {"    ", "NAME",  0, FALSE},
  36.   {"8SVX", "CHAN",  0, FALSE},
  37.   {"8SVX", "PAN ",  0, FALSE},
  38.   {"8SVX", "FADE",  0, FALSE},
  39.   {"8SVX", "SEQN",  0, FALSE},
  40.   {"8SVX", "VHDR",  0, FALSE},
  41.   {"AIFF", "APPL",  4, TRUE },
  42.   {"AIFF", "COMM",  8, TRUE }, // we currently ignore 'SampleRate' field
  43.   {"AIFF", "COMT",  0, FALSE},
  44.   {"AIFF", "MARK",  0, FALSE},
  45.   {"AIFF", "SSND",  8, TRUE },
  46.   {"AIFF", "INST",  0, FALSE},
  47.   {"FTXT", "FONS",  0, FALSE},
  48.   {"HEAD", "NEST",  0, FALSE},
  49.   {"!!!!", "BMHD",  0, FALSE}, // "!!!!" means "ACBM or ILBM"
  50.   {"!!!!", "CAMG",  0, FALSE},
  51.   {"!!!!", "GRAB",  0, FALSE},
  52.   {"!!!!", "DPI ",  0, FALSE},
  53.   {"!!!!", "DEST",  0, FALSE},
  54.   {"!!!!", "EPSF",  8, TRUE },
  55.   {"!!!!", "SPRT",  0, FALSE},
  56.   {"SMUS", "INS1",  0, FALSE},
  57.   {"SMUS", "SHDR",  0, FALSE},
  58.   {"WORD", "FONT",  0, FALSE},
  59.   {"WORD", "COLR",  0, FALSE},
  60.   {"WORD", "DOC ",  0, FALSE},
  61.   {"WORD", "HEAD",  0, FALSE},
  62.   {"WORD", "FOOT",  0, FALSE},
  63.   {"WORD", "PCTS",  0, FALSE},
  64.   {"WORD", "PARA",  0, FALSE},
  65.   {"WORD", "TABS",  0, FALSE},
  66.   {"WORD", "PINF",  0, FALSE},
  67.   {"####", "FSCC",  0, FALSE}  // "####" means "HEAD or WORD"
  68. };
  69.  
  70. #define ITEMS 255
  71. MODULE struct
  72. {   TEXT   name[5];
  73.     ULONG  bytes;
  74.     UBYTE* DataPtr;
  75. } contents[ITEMS + 1];
  76.  
  77. #define FORMS         89
  78.  
  79. #define CD             1
  80. #define OBSOLETE       2
  81. #define PRIVATE        4
  82. #define PROPOSAL       8
  83. #define RESERVED      16
  84. #define RKM           32
  85. #define STANDARD      64
  86. #define UNREGISTERED 128
  87.  
  88. #define IFFXCHARS     17
  89.  
  90. MODULE void iffquery(void);
  91. MODULE void PrintTopChunk(void);
  92. MODULE void readiff(void);
  93. MODULE void tellchunk(UWORD which);
  94. MODULE void chunkdesc(STRPTR desc);
  95. MODULE void binarize(UBYTE data);
  96. MODULE ULONG getulong(UBYTE* start);
  97. MODULE SLONG getslong(UBYTE* start);
  98. MODULE ULONG getuword(UBYTE* start);
  99. MODULE SLONG getsword(UBYTE* start);
  100. MODULE SLONG getsbyte(UBYTE* start);
  101. MODULE struct List* clearlist(struct Gadget* GadgetPtr, struct List* ListPtr);
  102. MODULE void writeiffgadgets(void);
  103.  
  104. /* Text error messages for possible IFFERR_#? returns from various IFF
  105.  * routines. To get the index into this array, take your IFFERR code,
  106.  * negate it, and subtract one.
  107.  * idx = -error - 1;
  108.  */
  109. STRPTR errormsgs[] =
  110. {   "End of file (not an error).",
  111.     "End of context (not an error).",
  112.     "No lexical scope.",
  113.     "Insufficient memory.",
  114.     "Stream read error.",
  115.     "Stream write error.",
  116.     "Stream seek error.",
  117.     "File is corrupt.",
  118.     "IFF syntax error.",
  119.     "Not an IFF file.",
  120.     "Required call-back hook missing.",
  121.     "Return to client. You should never see this."
  122. };
  123.  
  124. // from rp.c
  125. IMPORT ABOOL             fillwindows;
  126. IMPORT SBYTE             page;
  127. IMPORT struct NewGadget  Gadget;
  128. IMPORT struct Gadget    *BU99_Right,
  129.                         *PrevGadPtr;
  130. IMPORT struct Window*    MainWindowPtr;
  131. IMPORT TEXT              aslresult[VLONGFIELD + 1],
  132.                          weekdaystring[LEN_DATSTRING],
  133.                          datestring[LEN_DATSTRING],
  134.                          timestring[LEN_DATSTRING];
  135.  
  136. MODULE ABOOL             known;
  137. MODULE struct IFFHandle* IFFHandle             = NULL;
  138. MODULE struct List      *List1Ptr              = NULL,
  139.                         *List2Ptr              = NULL;
  140. MODULE struct Gadget  *TE61_Contributor        = NULL,
  141.                       *CB61_CD                 = NULL,
  142.                       *CB61_Obsolete           = NULL,
  143.                       *TE61_FORMDesc           = NULL,
  144.                       *ST61_FORMID             = NULL,
  145.                       *CB61_Private            = NULL,
  146.                       *CB61_Proposal           = NULL,
  147.                       *CB61_Reserved           = NULL,
  148.                       *CB61_RKM                = NULL,
  149.                       *CB61_Standard           = NULL,
  150.                       *CB61_Unregistered       = NULL,
  151.                       *TE61_Status             = NULL,
  152.                       *ST61_Pathname           = NULL,
  153.                       *BU61_PathnameASL        = NULL,
  154.                       *LV61_List1              = NULL,
  155.                       *LV61_List2              = NULL,
  156.                       *TE61_ChunkDesc          = NULL;
  157. MODULE TEXT  queryform[5] = "",
  158.              tempstring1[VLONGFIELD + 1],
  159.              tempstring2[13];
  160. MODULE ULONG items = 0; // value of this is actual number of items allocated
  161. MODULE UWORD selectedform = 0;
  162. AGLOBAL struct IFFStruct iff;
  163. MODULE struct
  164. {   UBYTE  flags;
  165.     TEXT   name[5];
  166.     STRPTR desc;
  167.     STRPTR contributor;
  168. } form[FORMS + 1] =
  169. {   STANDARD | RKM | CD,      "8SVX", "EA IFF 85 8-bit sound sample form",                    "EA/CBM",
  170.     RKM | CD,                 "AIFF", "Audio 1-32 bit samples",                               "Apple",
  171.     RKM | CD,                 "ACBM", "Amiga Contiguous Bitmap",                              "CBM",
  172.     UNREGISTERED,             "AHAM", "?",                                                    "?",
  173.     RKM | CD,                 "ANBM", "Animated BitMap form",                                 "EA",
  174.     RKM | CD,                 "ANIM", "CEL ANIMation form",                                   "Sparta/Aegis",
  175.     PROPOSAL,                 "ARC ", "ARChive format",                                       "?",
  176.     UNREGISTERED,             "ARES", "?",                                                    "?",
  177.     RESERVED,                 "ATXT", "Temporarily reserved",                                 "?",
  178.     PRIVATE,                  "AVCF", "AmigaVision Flow",                                     "CBM",
  179.     NULL,                     "BANK", "Soundquest Editor/Librarian MIDI Sysex dump",          "?",
  180.     NULL,                     "BBSD", "BBS Database",                                         "Phalanx Software",
  181.     PRIVATE,                  "C100", "?",                                                    "Cloanto",
  182.     STANDARD,                 "CAT ", "EA IFF 85 group identifier",                           "EA/CBM",
  183.     PROPOSAL,                 "CELP", "Compressed ZyXEL voice data",                          "?",
  184.     RESERVED,                 "CHBM", "Chunky bitmap",                                        "Eric Lavitsky",
  185.     NULL,                     "CLIP", "CAT CLIP to hold various formats in clipboard",        "CBM",
  186.     PROPOSAL | CD,            "CMUS", "Common MUsical Score",                                 "Talin (David Joiner)",
  187.     NULL,                     "CPFM", "Cloanto Personal FontMaker",                           "Cloanto",
  188.     NULL,                     "DCCL", "DCTV paint clip",                                      "?",
  189.     NULL,                     "DCPA", "DCTV paint palette",                                   "?",
  190.     NULL,                     "DCTV", "DCTV raw picture file",                                "?",
  191.     PRIVATE,                  "DECK", "Inovatronics CanDo",                                   "Innovatronics",
  192.     CD,                       "DEEP", "Chunky pixel image files (used in TV Paint)",          "Amiga Centre Scotland",
  193.     RKM | CD,                 "DR2D", "2D object standard format",                            "Ross Cunniff & John Orr",
  194.     RESERVED,                 "DRAW", "?",                                                    "Jim Bayless",
  195.     CD,                       "DTYP", "DataTYPes identification",                             "Amiga, Inc.",
  196.     PROPOSAL | CD,            "EXEC", "Executable (loadseg-able) code",                       "Chris Ludwig",
  197.     RKM | CD,                 "FANT", "Fantavision movie format",                             "Broderbund",
  198.     OBSOLETE | PRIVATE,       "FAX3", "Facsimile image",                                      "GPSoftware",
  199.     CD,                       "FAXX", "Facsimile image",                                      "Atlantis Design Group",
  200.     RESERVED,                 "FIGR", "Deluxe Video",                                         "EA",
  201.     NULL,                     "FILM", "LIST FILM - stores ILBMs with interleaved 8SVX audio", "?",
  202.     RESERVED,                 "FNTR", "Raster font",                                          "EA",
  203.     RESERVED,                 "FNTV", "Vector font",                                          "EA",
  204.     STANDARD,                 "FORM", "Group identifier",                                     "EA/CBM",
  205.     STANDARD | RKM,           "FTXT", "Formatted TeXT",                                       "EA/CBM",
  206.     PROPOSAL | PRIVATE,       "GRYP", "Byteplane storage",                                    "?",
  207.     RESERVED,                 "GSCR", "General music SCoRe",                                  "EA",
  208.     PROPOSAL | PRIVATE,       "GUI ", "User interface storage",                               "?",
  209.     RKM | CD,                 "HEAD", "Flow idea processor",                                  "New Horizons Software",
  210.     STANDARD | RKM | CD,      "ILBM", "EA IFF 85 raster bitmap form",                         "EA/CBM",
  211.     RESERVED,                 "IOBJ", "?",                                                    "Seven Seas Software",
  212.     RESERVED,                 "IODK", "?",                                                    "Merging Technologies",
  213.     RESERVED,                 "ITRF", "?",                                                    "?",
  214.     RESERVED,                 "JMOV", "?",                                                    "Merging Technologies",
  215.     STANDARD,                 "LIST", "EA IFF 85 group identifier",                           "EA/CBM",
  216.     RESERVED,                 "MFAX", "Facsimile?",                                           "TKR GmbH & Co.",
  217.     NULL,                     "MIDI", "MIDI?",                                                "Circum Design",
  218.     PRIVATE,                  "MOVI", "LIST MOVIe?",                                          "?",
  219.     PRIVATE,                  "MSCX", "Music-X format",                                       "?",
  220.     RESERVED,                 "MSMP", "Temporarily reserved",                                 "?",
  221.     RKM | CD,                 "MTRX", "Numerical data storage (MathVision)",                  "Seven Seas Software",
  222.     NULL,                     "NSEQ", "Numerical sequence",                                   "Stockhausen GmbH",
  223.     PROPOSAL | CD,            "OB3D", "Standard 3D object",                                   "?",
  224.     RKM | CD,                 "PGTB", "ProGram TraceBack",                                    "SAS Institute",
  225.     RESERVED,                 "PICS", "Macintosh picture",                                    "EA",
  226.     RESERVED | OBSOLETE,      "PLBM", "?",                                                    "EA",
  227.     RESERVED | PROPOSAL | CD, "PMBC", "24-bit accurate images",                               "Black Belt Systems",
  228.     RESERVED | PRIVATE,       "PREF", "User preferences data",                                "CBM",
  229.     STANDARD,                 "PROP", "Group identifier",                                     "EA/CBM",
  230.     RKM | CD,                 "PRSP", "DPaint IV perspective move form",                      "EA",
  231.     NULL,                     "PTCH", "Patch file",                                           "SAS Institute",
  232.     RESERVED,                 "PTXT", "Temporarily reserved",                                 "?",
  233.     NULL,                     "RGB4", "4-bit RGB",                                            "?",
  234.     RKM | CD,                 "RGB8", "RGB image (Turbo Silver)",                             "Impulse",
  235.     RKM | CD,                 "RGBN", "RGB image (Turbo Silver)",                             "Impulse",
  236.     RESERVED,                 "RGBX", "Temporarily reserved",                                 "?",
  237.     PRIVATE,                  "ROXN", "Animation",                                            "?",
  238.     RKM | CD,                 "SAMP", "Sampled sound",                                        "Jim Fiore & Jeff Glatt",
  239.     PRIVATE,                  "SC3D", "SCene format (Sculpt-3D)",                             "?",
  240.     PRIVATE,                  "SHAK", "SHAKespeare format",                                   "?",
  241.     RESERVED | PRIVATE,       "SHO1", "?",                                                    "Gary Bonham",
  242.     RESERVED | PRIVATE,       "SHOW", "?",                                                    "Gary Bonham",
  243.     STANDARD | RKM,           "SMUS", "Simple MUsic Score",                                   "EA/CBM",
  244.     CD,                       "SPLT", "File SPLiTting system",                                "ASDG",
  245.     RESERVED,                 "SSRE", "?",                                                    "Merging Technologies",
  246.     UNREGISTERED,             "SWRT", "?",                                                    "?",
  247.     NULL,                     "SYTH", "SoundQuest Master Librarian MIDI System driver",       "?",
  248.     RESERVED,                 "TCDE", "?",                                                    "Merging Technologies",
  249.     RKM | CD,                 "TDDD", "3D rendering data (Turbo Silver)",                     "Impulse",
  250.     UNREGISTERED,             "TERM", "?",                                                    "?",
  251.     CD,                       "TMUI", "ToolMaker User Interface",                             "Michael Erwin",
  252.     CD,                       "TREE", "Arbitrary data structures as trees (or nested lists)", "Stefan Reisner",
  253.     CD | PROPOSAL,            "TRKR", "TRacKeR style music module",                           "Full Tilt Entertainment",
  254.     RESERVED,                 "USCR", "Uhuru SCoRe",                                          "EA",
  255.     RESERVED,                 "UVOX", "Uhuru Macintosh VOiXe",                                "EA",
  256.     PRIVATE,                  "VDEO", "Deluxe ViDEO",                                         "EA",
  257.     RKM | CD,                 "WORD", "ProWrite document",                                    "New Horizons Software",
  258.     CD,                       "YUVN", "For storage of Y:U:V image data",                      "MacroSystem"
  259. };
  260.  
  261. AGLOBAL void iff1(void)
  262. {   verynewwindow
  263.     (   IFF1WIDTH, IFF1HEIGHT,
  264.         "Report+: IFF Registry",
  265.         BUTTONIDCMP | STRINGIDCMP | LISTVIEWIDCMP
  266.     );
  267.     if (fillwindows)
  268.     {   SetAPen(MainWindowPtr->RPort, 0);
  269.         RectFill(MainWindowPtr->RPort,  10, 120,  10 + 160, 120 +  68 - 1); // LV61_List1
  270.         RectFill(MainWindowPtr->RPort, 180, 120, 180 + 450, 120 +  68 - 1); // LV61_List2
  271.         RectFill(MainWindowPtr->RPort, 130,  34, 130 + 440,  34 +  12); // TE61_FORMDesc
  272.         RectFill(MainWindowPtr->RPort, 130,  46, 130 + 440,  46 +  12); // TE61_Contributor
  273.         RectFill(MainWindowPtr->RPort, 130,  58, 130 + 440,  58 +  12); // TE61_ChunkDesc
  274.         RectFill(MainWindowPtr->RPort, 130, 200, 130 + 350, 200 +  12); // TE61_Status
  275.     }
  276.  
  277.     /* FORM ID */
  278.     setgadget(130, 22, 56, 12, "_FORM ID:", NULL);
  279.     ST61_FORMID = PrevGadPtr = (struct Gadget *) CreateGadget
  280.     (   STRING_KIND,
  281.         PrevGadPtr,
  282.         &Gadget,
  283.         GTST_String, queryform,
  284.         GTST_MaxChars, 4,
  285.         GA_TabCycle, TRUE,
  286.         GA_Immediate, TRUE,
  287.         GT_Underscore, '_',
  288.         STRINGA_ReplaceMode, TRUE,
  289.         TAG_DONE
  290.     );
  291.     /* FORM description */
  292.     setgadget(130, 34, 440, 12, "Description:", NULL);
  293.     TE61_FORMDesc = PrevGadPtr = (struct Gadget *) CreateGadget
  294.     (   TEXT_KIND,
  295.         PrevGadPtr,
  296.         &Gadget,
  297.         GTTX_Text, "-",
  298.         GTTX_Border, TRUE,
  299.         TAG_DONE
  300.     );
  301.     /* contributor name */
  302.     setgadget(130, 46, 440, 12, "Contributor:", NULL);
  303.     TE61_Contributor = PrevGadPtr = (struct Gadget *) CreateGadget
  304.     (   TEXT_KIND,
  305.         PrevGadPtr,
  306.         &Gadget,
  307.         GTTX_Text, "-",
  308.         GTTX_Border, TRUE,
  309.         TAG_DONE
  310.     );
  311.     /* chunk description */
  312.     setgadget(130, 58, 440, 12, "Chunk info:", NULL);
  313.     TE61_ChunkDesc = PrevGadPtr = (struct Gadget *) CreateGadget
  314.     (   TEXT_KIND,
  315.         PrevGadPtr,
  316.         &Gadget,
  317.         GTTX_Text, "-",
  318.         GTTX_Border, TRUE,
  319.         TAG_DONE
  320.     );
  321.  
  322.     /* flags */
  323.     setgadget(130, 76, 0, 0, "Obsolete:", NULL);
  324.     CB61_Obsolete = PrevGadPtr = (struct Gadget *) CreateGadget
  325.     (   CHECKBOX_KIND,
  326.         PrevGadPtr,
  327.         &Gadget,
  328.         GA_Disabled, TRUE,
  329.         GTCB_Checked, iff.obsolete,
  330.         TAG_DONE
  331.     );
  332.     setgadget(130, 90, 0, 0, "Private:", NULL);
  333.     CB61_Private = PrevGadPtr = (struct Gadget *) CreateGadget
  334.     (   CHECKBOX_KIND,
  335.         PrevGadPtr,
  336.         &Gadget,
  337.         GA_Disabled, TRUE,
  338.         GTCB_Checked, iff.private,
  339.         TAG_DONE
  340.     );
  341.     setgadget(282, 76, 0, 0, "Proposal:", NULL);
  342.     CB61_Proposal = PrevGadPtr = (struct Gadget *) CreateGadget
  343.     (   CHECKBOX_KIND,
  344.         PrevGadPtr,
  345.         &Gadget,
  346.         GA_Disabled, TRUE,
  347.         GTCB_Checked, iff.proposal,
  348.         TAG_DONE
  349.     );
  350.     setgadget(282, 90, 0, 0, "Reserved:", NULL);
  351.     CB61_Reserved = PrevGadPtr = (struct Gadget *) CreateGadget
  352.     (   CHECKBOX_KIND,
  353.         PrevGadPtr,
  354.         &Gadget,
  355.         GA_Disabled, TRUE,
  356.         GTCB_Checked, iff.reserved,
  357.         TAG_DONE
  358.     );
  359.     setgadget(434, 76, 0, 0, "Standard:", NULL);
  360.     CB61_Standard = PrevGadPtr = (struct Gadget *) CreateGadget
  361.     (   CHECKBOX_KIND,
  362.         PrevGadPtr,
  363.         &Gadget,
  364.         GA_Disabled, TRUE,
  365.         GTCB_Checked, iff.standard,
  366.         TAG_DONE
  367.     );
  368.     setgadget(434, 90, 0, 0, "Unregistered:", NULL);
  369.     CB61_Unregistered = PrevGadPtr = (struct Gadget *) CreateGadget
  370.     (   CHECKBOX_KIND,
  371.         PrevGadPtr,
  372.         &Gadget,
  373.         GA_Disabled, TRUE,
  374.         GTCB_Checked, iff.unregistered,
  375.         TAG_DONE
  376.     );
  377.     setgadget(588, 76, 0, 0, "RKM:", NULL);
  378.     CB61_RKM = PrevGadPtr = (struct Gadget *) CreateGadget
  379.     (   CHECKBOX_KIND,
  380.         PrevGadPtr,
  381.         &Gadget,
  382.         GA_Disabled, TRUE,
  383.         GTCB_Checked, iff.rkm,
  384.         TAG_DONE
  385.     );
  386.     setgadget(588, 90, 0, 0, "CD-ROM:", NULL);
  387.     CB61_CD = PrevGadPtr = (struct Gadget *) CreateGadget
  388.     (   CHECKBOX_KIND,
  389.         PrevGadPtr,
  390.         &Gadget,
  391.         GA_Disabled, TRUE,
  392.         GTCB_Checked, iff.cd,
  393.         TAG_DONE
  394.     );
  395.  
  396.     setgadget( 10, 120, 160, 68, "Chunks:", NULL);
  397.     LV61_List1 = PrevGadPtr = (struct Gadget *) CreateGadget
  398.     (   LISTVIEW_KIND,
  399.         PrevGadPtr,
  400.         &Gadget,
  401.         GTLV_Labels, NULL,
  402.         GTLV_ShowSelected, NULL,
  403.         TAG_DONE
  404.     );
  405.     setgadget(180, 120, 450, 68, "Chunk contents:", NULL);
  406.     LV61_List2 = PrevGadPtr = (struct Gadget *) CreateGadget
  407.     (   LISTVIEW_KIND,
  408.         PrevGadPtr,
  409.         &Gadget,
  410.         GTLV_Labels, NULL,
  411.         TAG_DONE
  412.     );
  413.  
  414.     /* status */
  415.     setgadget(130, 200, 350, 12, "Status:", NULL);
  416.     TE61_Status = PrevGadPtr = (struct Gadget *) CreateGadget
  417.     (   TEXT_KIND,
  418.         PrevGadPtr,
  419.         &Gadget,
  420.         GTTX_Text, "Ready.",
  421.         GTTX_Border, TRUE,
  422.         TAG_DONE
  423.     );
  424.  
  425.     /* pathname */
  426.     setgadget(130, 214, 320, 12, "_Pathname:", NULL);
  427.     ST61_Pathname = PrevGadPtr = (struct Gadget *) CreateGadget
  428.     (   STRING_KIND,
  429.         PrevGadPtr,
  430.         &Gadget,
  431.         GTST_String, iff.pathname,
  432.         GTST_MaxChars, VLONGFIELD,
  433.         GA_TabCycle, TRUE,
  434.         GA_Immediate, TRUE,
  435.         GT_Underscore, '_',
  436.         TAG_DONE
  437.     );
  438.     /* pathname... */
  439.     setgadget(452, 214, 28, 12, "_...", NULL);
  440.     BU61_PathnameASL = PrevGadPtr = (struct Gadget *) CreateGadget
  441.     (   BUTTON_KIND,
  442.         PrevGadPtr,
  443.         &Gadget,
  444.         GT_Underscore, '_',
  445.         TAG_DONE
  446.     );
  447.  
  448.     drawgadgets((UWORD) ~0);
  449.     if (iff.pathname[0])
  450.     {   readiff();
  451.     } elif (queryform[0])
  452.     {   iffquery();
  453.     }
  454.     ActivateGadget(ST61_Pathname, MainWindowPtr, NULL);
  455.     loop();
  456.     strcpy
  457.     (   queryform,
  458.         ((struct StringInfo *) ST61_FORMID->SpecialInfo)->Buffer
  459.     );
  460.     strcpy
  461.     (   iff.pathname,
  462.         ((struct StringInfo *) ST61_Pathname->SpecialInfo)->Buffer
  463.     );
  464.     closewindow();
  465. }
  466.  
  467. AGLOBAL void iff_loop(ULONG class, struct Gadget* addr, UWORD code, UWORD qual)
  468. {   if (class == IDCMP_VANILLAKEY)
  469.     {   code = toupper(code);
  470.         if (code == ESCAPE)
  471.             page = 0;
  472.         elif (code == 'F')
  473.             ActivateGadget(ST61_FORMID, MainWindowPtr, NULL);
  474.         elif (code == 'P')
  475.             ActivateGadget(ST61_Pathname, MainWindowPtr, NULL);
  476.         elif (code == '.')
  477.         {   if (asl())
  478.             {   strcpy(iff.pathname, aslresult);
  479.                 GT_SetGadgetAttrs
  480.                 (   ST61_Pathname,
  481.                     MainWindowPtr,
  482.                     NULL,
  483.                     GTST_String, iff.pathname,
  484.                     TAG_DONE
  485.                 );
  486.                 readiff();
  487.     }   }   }
  488.     elif (class == IDCMP_GADGETUP)
  489.     {   /* IDCMP_GADGETUP is sent by the string gadget
  490.         when the user presses RETURN, ENTER, Help, Tab
  491.         or Shift-Tab inside the string gadget. */
  492.         
  493.         if (addr == BU99_Right)
  494.             page = 0;
  495.         elif (addr == ST61_Pathname)
  496.     {   strcpy
  497.             (   iff.pathname,
  498.                 ((struct StringInfo *) ST61_Pathname->SpecialInfo)->Buffer
  499.         );
  500.             readiff();
  501.         } elif (addr == ST61_FORMID)
  502.         {   strcpy
  503.             (   queryform,
  504.                 ((struct StringInfo *) ST61_FORMID->SpecialInfo)->Buffer
  505.         );
  506.             iff.pathname[0] = 0;
  507.             GT_SetGadgetAttrs
  508.             (   ST61_Pathname,
  509.                 MainWindowPtr,
  510.                 NULL,
  511.                 GTST_String, iff.pathname,
  512.                 TAG_DONE
  513.             );
  514.             GT_SetGadgetAttrs
  515.             (   TE61_Status,
  516.                 MainWindowPtr,
  517.                 NULL,
  518.                 GTTX_Text, "Ready.",
  519.                 TAG_DONE
  520.             );
  521.             iffquery();
  522.         } elif (addr == BU61_PathnameASL)
  523.         {   if (asl())
  524.             {   strcpy(iff.pathname, aslresult);
  525.                 GT_SetGadgetAttrs
  526.                 (   ST61_Pathname,
  527.                     MainWindowPtr,
  528.                     NULL,
  529.                     GTST_String, iff.pathname,
  530.                     TAG_DONE
  531.                 );
  532.                 readiff();
  533.         }   }
  534.         elif (addr == LV61_List1)
  535.         {   tellchunk(code + 1);
  536. }   }   }
  537.  
  538. MODULE void iffquery(void)
  539. {   ULONG i;
  540.  
  541.     /* Make any corrections to input now, to make it
  542.     easier to search the database. */
  543.     for (i = 0; i <= 3; i++)
  544.         if (queryform[i] >= 97 && queryform[i] <= 122)
  545.             queryform[i] -= 32;
  546.         elif (queryform[i] == 0)
  547.             queryform[i] = ' ';
  548.     queryform[4] = 0;
  549.     GT_SetGadgetAttrs
  550.     (   ST61_FORMID,
  551.         MainWindowPtr,
  552.         NULL,
  553.         GTTX_Text, queryform,
  554.         TAG_DONE
  555.     );
  556.     selectedform = (UWORD) -1;
  557.     for (i = 0; i <= FORMS; i++)
  558.     if
  559.     (   queryform[0] == form[i].name[0]
  560.      && queryform[1] == form[i].name[1]
  561.      && queryform[2] == form[i].name[2]
  562.      && queryform[3] == form[i].name[3]
  563.     )
  564.     {   selectedform = i;
  565.         break;
  566.     }
  567.     if (selectedform == (UWORD) -1)
  568.     {   iff.cd           =
  569.         iff.rkm          =
  570.         iff.private      =
  571.         iff.proposal     =
  572.         iff.obsolete     =
  573.         iff.reserved     =
  574.         iff.standard     =
  575.         iff.unregistered = FALSE;
  576.         GT_SetGadgetAttrs
  577.         (   TE61_FORMDesc,
  578.             MainWindowPtr,
  579.             NULL,
  580.             GTTX_Text, "-",
  581.             TAG_DONE
  582.         );
  583.         GT_SetGadgetAttrs
  584.         (   TE61_Contributor,
  585.             MainWindowPtr,
  586.             NULL,
  587.             GTTX_Text, "-",
  588.             TAG_DONE
  589.         );
  590.     } else
  591.     {   iff.cd           = form[selectedform].flags & CD;
  592.         iff.rkm          = form[selectedform].flags & RKM;
  593.         iff.private      = form[selectedform].flags & PRIVATE;
  594.         iff.proposal     = form[selectedform].flags & PROPOSAL;
  595.         iff.obsolete     = form[selectedform].flags & OBSOLETE;
  596.         iff.reserved     = form[selectedform].flags & RESERVED;
  597.         iff.standard     = form[selectedform].flags & STANDARD;
  598.         iff.unregistered = form[selectedform].flags & UNREGISTERED;
  599.         GT_SetGadgetAttrs
  600.         (   TE61_FORMDesc,
  601.             MainWindowPtr,
  602.             NULL,
  603.             GTTX_Text, form[selectedform].desc,
  604.             TAG_DONE
  605.         );
  606.         GT_SetGadgetAttrs
  607.         (   TE61_Contributor,
  608.             MainWindowPtr,
  609.             NULL,
  610.             GTTX_Text, form[selectedform].contributor,
  611.             TAG_DONE
  612.         );
  613.     }
  614.  
  615.     writeiffgadgets();
  616.  
  617.     List1Ptr = clearlist(LV61_List1, List1Ptr);
  618.     List2Ptr = clearlist(LV61_List2, List2Ptr);
  619.     for (i = 0; i < items; i++)
  620.     {   if (contents[i].DataPtr)
  621.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  622.             contents[i].DataPtr = NULL;
  623.     }   }
  624.     items = 0;
  625. }
  626.  
  627. MODULE void readiff(void)
  628. {   LONG error;
  629.  
  630.     iffquery();
  631.  
  632.     /* Allocate IFF_File structure. */
  633.     if (!(IFFHandle = AllocIFF()))
  634.     {   DisplayBeep(NULL);
  635.         GT_SetGadgetAttrs
  636.         (   TE61_Status,
  637.             MainWindowPtr,
  638.             NULL,
  639.             GTTX_Text, "AllocIFF() failed!",
  640.             TAG_DONE
  641.         );
  642.         goto bye;
  643.     }
  644.  
  645.     /* Set up IFF_File for AmigaDOS I/O.  */
  646.     if (!(IFFHandle->iff_Stream = Open(iff.pathname, MODE_OLDFILE)))
  647.     {   DisplayBeep(NULL);
  648.         GT_SetGadgetAttrs
  649.         (   TE61_Status,
  650.             MainWindowPtr,
  651.             NULL,
  652.             GTTX_Text, "Can't open file!",
  653.             TAG_DONE
  654.         );
  655.         GT_SetGadgetAttrs
  656.         (   TE61_FORMDesc,
  657.             MainWindowPtr,
  658.             NULL,
  659.             GTTX_Text, "-",
  660.             TAG_DONE
  661.         );
  662.         GT_SetGadgetAttrs
  663.         (   TE61_Contributor,
  664.             MainWindowPtr,
  665.             NULL,
  666.             GTTX_Text, "-",
  667.             TAG_DONE
  668.         );
  669.         queryform[0]     = 0;
  670.         iff.obsolete     =
  671.         iff.private      =
  672.         iff.proposal     =
  673.         iff.reserved     =
  674.         iff.standard     =
  675.         iff.unregistered =
  676.         iff.rkm          =
  677.         iff.cd           = FALSE;
  678.         writeiffgadgets();
  679.         goto bye;
  680.     }
  681.     InitIFFasDOS(IFFHandle);
  682.  
  683.     /* Start the IFF transaction. */
  684.     if (error = OpenIFF(IFFHandle, IFFF_READ))
  685.     {   DisplayBeep(NULL);
  686.         GT_SetGadgetAttrs
  687.         (   TE61_Status,
  688.             MainWindowPtr,
  689.             NULL,
  690.             GTTX_Text, "OpenIFF() failed!",
  691.             TAG_DONE
  692.         );
  693.         goto bye;
  694.     }
  695.  
  696.     while (1)
  697.     {   /* IFFPARSE_RAWSTEP permits us to have precision monitoring of the
  698.          * parsing process, which is necessary if we wish to print the
  699.          * structure of an IFF file.
  700.          *   ParseIFF() with _RAWSTEP will return the following things for
  701.          * the following reasons:
  702.          *
  703.          * Return code:                 Reason:
  704.          * 0                            Entered new context.
  705.          * IFFERR_EOC                   About to leave a context.
  706.          * IFFERR_EOF                   Encountered end-of-file.
  707.          * <anything else>              A parsing error.
  708.          */
  709.         error = ParseIFF(IFFHandle, IFFPARSE_RAWSTEP);
  710.  
  711.         /*
  712.          * Since we're only interested in when we enter a context, we
  713.          * "discard" end-of-context (_EOC) events.
  714.          */
  715.         if (error == IFFERR_EOC)
  716.             continue;
  717.         elif (error)
  718.         {   // Leave the loop if there is any other error.
  719.             break;
  720.         }
  721.  
  722.         /* If we get here, error was zero. Print out the current state of
  723.          * affairs. */
  724.         PrintTopChunk();
  725.     }
  726.  
  727.     /* If error was IFFERR_EOF, then the parser encountered the end of
  728.      * the file without problems. Otherwise, we print a diagnostic.
  729.      */
  730.     if (error == IFFERR_EOF)
  731.     {   GT_SetGadgetAttrs
  732.         (   TE61_Status,
  733.             MainWindowPtr,
  734.             NULL,
  735.             GTTX_Text, "Done.",
  736.             TAG_DONE
  737.         );
  738.         GT_SetGadgetAttrs
  739.         (   LV61_List1,
  740.             MainWindowPtr,
  741.             NULL,
  742.             GTLV_Labels, List1Ptr,
  743.             GTLV_Selected, (UWORD) ~0,
  744.             TAG_DONE
  745.         );
  746.     } else
  747.     {   GT_SetGadgetAttrs
  748.         (   TE61_Status,
  749.             MainWindowPtr,
  750.             NULL,
  751.             GTTX_Text, errormsgs[-error - 1],
  752.             TAG_DONE
  753.         );
  754.         GT_SetGadgetAttrs
  755.         (   LV61_List1,
  756.             MainWindowPtr,
  757.             NULL,
  758.             GTLV_Labels, NULL,
  759.             TAG_DONE
  760.         );
  761.     }
  762.  
  763. bye:
  764.     if (IFFHandle)
  765.     {   /* Terminate the IFF transaction with the stream. Free all
  766.          * associated structures. */
  767.         CloseIFF(IFFHandle);
  768.         // Close the stream itself.
  769.         if (IFFHandle->iff_Stream)
  770.         {   Close(IFFHandle->iff_Stream);
  771.         }
  772.         // Free the IFF_File structure itself.
  773.         FreeIFF(IFFHandle);
  774.         IFFHandle = NULL;
  775. }   }
  776.  
  777. AGLOBAL void iff_exit(void)
  778. {   ULONG i;
  779.  
  780.     if (IFFHandle)
  781.     {   /* Terminate the IFF transaction with the stream. Free all
  782.          * associated structures. */
  783.         CloseIFF(IFFHandle);
  784.         // Close the stream itself.
  785.         if (IFFHandle->iff_Stream)
  786.         {   Close(IFFHandle->iff_Stream);
  787.         }
  788.         // Free the IFF_File structure itself.
  789.         FreeIFF(IFFHandle);
  790.         IFFHandle = NULL;
  791.     }
  792.  
  793.     if (List2Ptr)
  794.     {   FreeNameNodes(List2Ptr);
  795.         FreeMem(List1Ptr, sizeof(struct List));
  796.         List2Ptr = NULL;
  797.     }
  798.     if (List1Ptr)
  799.     {   FreeNameNodes(List1Ptr);
  800.         FreeMem(List1Ptr, sizeof(struct List));
  801.         List1Ptr = NULL;
  802.     }
  803.     for (i = 0; i < items; i++)
  804.     {   if (contents[i].DataPtr)
  805.         {   FreeMem(contents[i].DataPtr, contents[i].bytes);
  806.             contents[i].DataPtr = NULL;
  807.     }   }
  808.     items = 0;
  809. }
  810.  
  811. MODULE void PrintTopChunk(void)
  812. {   struct ContextNode* top;
  813.     short               i;
  814.     char                idbuf[5];
  815.     ULONG               length;
  816.  
  817.     /* Get a pointer to the context node describing the current context. */
  818.     if (!(top = CurrentChunk(IFFHandle)))
  819.         return;
  820.  
  821.     /* Print spaces equivalent to the current nesting depth of chunks
  822.      * processed so far.
  823.      *   This will cause nested chunks to be printed out indented. */
  824.  
  825.     strcpy(tempstring1, "");
  826.     for (i = IFFHandle->iff_Depth - 1; i--; )
  827.         strcat(tempstring1, " ");
  828.  
  829.     strcpy(contents[items].name, IDtoStr(top->cn_ID, idbuf));
  830.     contents[items].DataPtr = NULL;
  831.  
  832.     /* Print out the current chunk's ID and size. */
  833.     strcat(tempstring1, IDtoStr(top->cn_ID, idbuf));
  834.     stcl_d(tempstring2, top->cn_Size);
  835.  
  836.     length = IFFXCHARS - strlen(tempstring1) - strlen(tempstring2);
  837.     for (i = 1; i <= length; i++)
  838.     {   strcat(tempstring1, " ");
  839.     }
  840.     strcat(tempstring1, tempstring2);
  841.  
  842.     /* Print the current chunk's type, with a newline. */
  843.     AddNameToTail(List1Ptr, tempstring1);
  844.  
  845.     if (!strcmp(IDtoStr(top->cn_ID, idbuf), "FORM"))
  846.     {   strcpy(queryform, IDtoStr(top->cn_Type, idbuf));
  847.         iffquery();
  848.     } else
  849.     {   for (i = 0; i <= CHUNKS; i++)
  850.         {   if
  851.             (   (   !strcmp(queryform, chunks[i].formname)
  852.                  || !strcmp("    ", chunks[i].formname)
  853.                  || (!strcmp("!!!!", chunks[i].formname) && (!strcmp(queryform, "ILBM") || !strcmp(queryform, "ACBM")))
  854.                  || (!strcmp("####", chunks[i].formname) && (!strcmp(queryform, "WORD") || !strcmp(queryform, "HEAD")))
  855.                 )
  856.              && !strcmp(IDtoStr(top->cn_ID, idbuf), chunks[i].chunkname)
  857.             )
  858.             {   if (!chunks[i].fixed)
  859.                 {   contents[items].bytes = top->cn_Size;
  860.                 } else
  861.                 {   contents[items].bytes = chunks[i].bytes;
  862.                 }
  863.                 if (!(contents[items].DataPtr = AllocMem(contents[items].bytes, MEMF_CLEAR)))
  864.                 {   rq("Out of memory!");
  865.                 }
  866.                 if (ReadChunkBytes(IFFHandle, contents[items].DataPtr, contents[items].bytes) < 0)
  867.                 {   rq("ReadChunkBytes() failed!");
  868.                 }
  869.     }   }   }
  870.     items++;
  871. }
  872.  
  873. MODULE void tellchunk(UWORD which)
  874. {   SLONG           svalue;
  875.     ULONG           i, uvalue, markers, currentpos;
  876.     struct DateTime DateTime;
  877.  
  878.     if (which == (UWORD) ~0)
  879.     {   return;
  880.     }
  881.  
  882.     GT_SetGadgetAttrs
  883.     (   LV61_List2,
  884.         MainWindowPtr,
  885.         NULL,
  886.         GTLV_Labels, (UWORD) ~0,
  887.         TAG_DONE
  888.     );
  889.     if (List2Ptr)
  890.     {   FreeNameNodes(List2Ptr);
  891.         FreeMem(List2Ptr, sizeof(struct List));
  892.         List2Ptr = NULL;
  893.     }
  894.     if (!(List2Ptr = AllocMem(sizeof(struct List), MEMF_CLEAR)))
  895.         rq("Out of memory!");
  896.     NewList(List2Ptr);
  897.  
  898.     /* We don't use clearlist() for the above because we want to end
  899.     with an empty list that is NOT attached to the gadget yet. */
  900.  
  901.     known = FALSE;
  902.  
  903.     if (!stricmp(contents[which].name, "FORM"))
  904.     {   chunkdesc("-");
  905.     } elif (!stricmp(contents[which].name, "(c) "))
  906.     {   chunkdesc("© Copyright");
  907.         strcpy(tempstring1, "© Copyright:        ");
  908.         strcat(tempstring1, contents[which].DataPtr);
  909.         AddNameToTail(List2Ptr, tempstring1);
  910.     } elif (!stricmp(contents[which].name, "AUTH"))
  911.     {   chunkdesc("Author");
  912.         strcpy(tempstring1, "Author:             ");
  913.         strcat(tempstring1, contents[which].DataPtr);
  914.         AddNameToTail(List2Ptr, tempstring1);
  915.     } elif (!stricmp(contents[which].name, "ANNO"))
  916.     {   chunkdesc("Annotation");
  917.         strcpy(tempstring1, "Annotation:         ");
  918.         strcat(tempstring1, contents[which].DataPtr);
  919.         AddNameToTail(List2Ptr, tempstring1);
  920.     } elif (!strcmp(contents[which].name, "NAME"))
  921.     {   chunkdesc("Name");
  922.         strcpy(tempstring1, "Name:               ");
  923.         strcat(tempstring1, contents[which].DataPtr);
  924.         AddNameToTail(List2Ptr, tempstring1);
  925.     } elif (!strcmp(queryform, "FTXT"))
  926.     {   if (!strcmp(contents[which].name, "FONS"))
  927.         {   chunkdesc("Font specifier");
  928.  
  929.             strcpy(tempstring1, "ID number:          ");
  930.             stcl_d(tempstring2, contents[which].DataPtr[0]);
  931.             strcat(tempstring1, tempstring2);
  932.             if (contents[which].DataPtr[0] > 9)
  933.             {   strcat(tempstring1, " (invalid)");
  934.             }
  935.             AddNameToTail(List2Ptr, tempstring1);
  936.  
  937.             // Next is a pad byte ([1]).
  938.  
  939.             strcpy(tempstring1, "Proportional?       ");
  940.             uvalue = contents[which].DataPtr[2];
  941.             if (uvalue == 0)
  942.             {   strcat(tempstring1, "Unknown");
  943.             } elif (uvalue == 1)
  944.             {   strcat(tempstring1, "No");
  945.             } elif (uvalue == 2)
  946.             {   strcat(tempstring1, "Yes");
  947.             } else strcat(tempstring1, "?"); // not the same as `Unknown', of course!
  948.             AddNameToTail(List2Ptr, tempstring1);
  949.  
  950.             strcpy(tempstring1, "Serifs?             ");
  951.             uvalue = contents[which].DataPtr[3];
  952.             if (uvalue == 0)
  953.             {   strcat(tempstring1, "Unknown");
  954.             } elif (uvalue == 1)
  955.             {   strcat(tempstring1, "No");
  956.             } elif (uvalue == 2)
  957.             {   strcat(tempstring1, "Yes");
  958.             } else strcat(tempstring1, "?"); // not the same as `Unknown', of course!
  959.             AddNameToTail(List2Ptr, tempstring1);
  960.  
  961.             strcpy(tempstring1, "Font name:          ");
  962.             strcat(tempstring1, &(contents[which].DataPtr[4]));
  963.             AddNameToTail(List2Ptr, tempstring1);
  964.         } elif (!strcmp(contents[which].name, "CHRS"))
  965.         {   chunkdesc("Stream of text");
  966.     }   }
  967.     elif (!strcmp(queryform, "SMUS"))
  968.     {   if (!strcmp(contents[which].name, "SHDR"))
  969.         {   chunkdesc("Global information for the score");
  970.  
  971.             strcpy(tempstring1, "Tempo:              ");
  972.             uvalue = getuword(contents[which].DataPtr);
  973.             uvalue = (uvalue << 7);
  974.             stcl_d(tempstring2, uvalue);
  975.             strcat(tempstring1, tempstring2);
  976.             strcat(tempstring1, " bpm");
  977.             AddNameToTail(List2Ptr, tempstring1);
  978.  
  979.             strcpy(tempstring1, "Volume:             ");
  980.             uvalue = contents[which].DataPtr[2];
  981.             stcl_d(tempstring2, uvalue);
  982.             strcat(tempstring1, tempstring2);
  983.             strcat(tempstring1, "/127");
  984.             AddNameToTail(List2Ptr, tempstring1);
  985.  
  986.             strcpy(tempstring1, "Tracks:             ");
  987.             uvalue = contents[which].DataPtr[3];
  988.             stcl_d(tempstring2, uvalue);
  989.             strcat(tempstring1, tempstring2);
  990.             AddNameToTail(List2Ptr, tempstring1);
  991.         } elif (!strcmp(contents[which].name, "INS1"))
  992.         {   chunkdesc("Identifies an instrument to use");
  993.  
  994.             strcpy(tempstring1, "Register number:    ");
  995.             stcl_d(tempstring2, contents[which].DataPtr[0]); // UBYTE
  996.             strcat(tempstring1, tempstring2);
  997.             AddNameToTail(List2Ptr, tempstring1);
  998.  
  999.             strcpy(tempstring1, "Reference type:     ");
  1000.             if (contents[which].DataPtr[1] == 0) // UBYTE
  1001.             {   strcat(tempstring1, "Find by name");
  1002.             } elif (contents[which].DataPtr[1] == 1)
  1003.             {   strcat(tempstring1, "Find on MIDI");
  1004.             } else strcat(tempstring1, "?");
  1005.             AddNameToTail(List2Ptr, tempstring1);
  1006.  
  1007.             strcpy(tempstring1, "MIDI channel:       ");
  1008.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  1009.             {   stcl_d(tempstring2, contents[which].DataPtr[2]); // UBYTE
  1010.                 strcat(tempstring1, tempstring2);
  1011.             } else strcat(tempstring1, "n/a");
  1012.             AddNameToTail(List2Ptr, tempstring1);
  1013.  
  1014.             strcpy(tempstring1, "MIDI preset:        ");
  1015.             if (contents[which].DataPtr[1] == 1) // if find on MIDI
  1016.             {   stcl_d(tempstring2, contents[which].DataPtr[3]); // UBYTE
  1017.                 strcat(tempstring1, tempstring2);
  1018.             } else strcat(tempstring1, "n/a");
  1019.             AddNameToTail(List2Ptr, tempstring1);
  1020.  
  1021.             strcpy(tempstring1, "Instrument name:    ");
  1022.             strcat(tempstring1, (STRPTR) contents[which].DataPtr + 4); // STRPTR
  1023.             AddNameToTail(List2Ptr, tempstring1);
  1024.         } elif (!strcmp(contents[which].name, "TRAK"))
  1025.         {   chunkdesc("Linear stream of events");
  1026.         } elif (!strcmp(contents[which].name, "INST"))
  1027.         {   chunkdesc("Obsolete; use INS1 instead");
  1028.         } elif (!strcmp(contents[which].name, "IRev")) // this could also perhaps be IREV
  1029.         {   chunkdesc("Instant Music private chunk");
  1030.         } elif (!strcmp(contents[which].name, "BIAS"))
  1031.         {   chunkdesc("Instant Music private chunk");
  1032.     }   }
  1033.     elif (!strcmp(queryform, "HEAD"))
  1034.     {   if (!strcmp(contents[which].name, "NEST"))
  1035.         {   chunkdesc("Nesting level");
  1036.  
  1037.             strcpy(tempstring1, "Nesting level:      ");
  1038.             uvalue = getuword(contents[which].DataPtr);
  1039.             stcl_d(tempstring2, uvalue);
  1040.             strcat(tempstring1, tempstring2);
  1041.             AddNameToTail(List2Ptr, tempstring1);
  1042.         } elif (!strcmp(contents[which].name, "TEXT"))
  1043.         {   chunkdesc("Heading text");
  1044.     }   }
  1045.     elif (!strcmp(queryform, "WORD"))
  1046.     {   if (!strcmp(contents[which].name, "FONT"))
  1047.         {   chunkdesc("Font name/number table");
  1048.  
  1049.             strcpy(tempstring1, "Number:             ");
  1050.             uvalue = contents[which].DataPtr[0]; // UBYTE
  1051.             stcl_d(tempstring2, uvalue);
  1052.             strcat(tempstring1, tempstring2);
  1053.             AddNameToTail(List2Ptr, tempstring1);
  1054.  
  1055.             strcpy(tempstring1, "Size:               ");
  1056.             uvalue = getuword(&contents[which].DataPtr[3]);
  1057.             stcl_d(tempstring2, uvalue);
  1058.             strcat(tempstring1, tempstring2);
  1059.             AddNameToTail(List2Ptr, tempstring1);
  1060.  
  1061.             strcpy(tempstring1, "Instrument name:    ");
  1062.             strcat(tempstring1, (STRPTR) contents[which].DataPtr + 3); // STRPTR
  1063.             AddNameToTail(List2Ptr, tempstring1);
  1064.         } elif (!strcmp(contents[which].name, "COLR"))
  1065.         {   chunkdesc("Colour translation table");
  1066.  
  1067.             for (i = 0; i <= 7; i++)
  1068.             {   strcpy(tempstring1, "Colour ");
  1069.                 stcl_d(tempstring2, i);
  1070.                 strcat(tempstring1, tempstring2);
  1071.                 strcat(tempstring1, ":           ");
  1072.                 uvalue = contents[which].DataPtr[i]; // UBYTE
  1073.                 stcl_d(tempstring2, uvalue);
  1074.                 strcat(tempstring1, tempstring2);
  1075.                 AddNameToTail(List2Ptr, tempstring1);
  1076.         }   }
  1077.         elif (!strcmp(contents[which].name, "DOC "))
  1078.         {   chunkdesc("Begin document section");
  1079.  
  1080.             strcpy(tempstring1, "Starting page:      ");
  1081.             uvalue = getuword(contents[which].DataPtr);
  1082.             stcl_d(tempstring2, uvalue);
  1083.             strcat(tempstring1, tempstring2);
  1084.             AddNameToTail(List2Ptr, tempstring1);
  1085.  
  1086.             strcpy(tempstring1, "Numbering style:    ");
  1087.             if (contents[which].DataPtr[2] == 0)
  1088.             {   strcat(tempstring1, "1, 2, 3...");
  1089.             } elif (contents[which].DataPtr[2] == 1)
  1090.             {   strcat(tempstring1, "I, II, III...");
  1091.             } elif (contents[which].DataPtr[2] == 2)
  1092.             {   strcat(tempstring1, "i, ii, iii...");
  1093.             } elif (contents[which].DataPtr[2] == 3)
  1094.             {   strcat(tempstring1, "A, B, C...");
  1095.             } elif (contents[which].DataPtr[2] == 4)
  1096.             {   strcat(tempstring1, "a, b, c...");
  1097.             } else
  1098.             {   strcat(tempstring1, "?");
  1099.             }
  1100.             AddNameToTail(List2Ptr, tempstring1);
  1101.         } elif (!strcmp(contents[which].name, "HEAD"))
  1102.         {   chunkdesc("Begin header section");
  1103.  
  1104.             strcpy(tempstring1, "Page type:           ");
  1105.             if (contents[which].DataPtr[0] == 0)
  1106.             {   strcat(tempstring1, "None");
  1107.             } elif (contents[which].DataPtr[0] == 1)
  1108.             {   strcat(tempstring1, "Left");
  1109.             } elif (contents[which].DataPtr[0] == 2)
  1110.             {   strcat(tempstring1, "Right");
  1111.             } elif (contents[which].DataPtr[0] == 3)
  1112.             {   strcat(tempstring1, "Both");
  1113.             } else strcat(tempstring1, "?");
  1114.             AddNameToTail(List2Ptr, tempstring1);
  1115.  
  1116.             strcpy(tempstring1, "First page?          ");
  1117.             if (contents[which].DataPtr[1] == 0)
  1118.             {   strcat(tempstring1, "No");
  1119.             } else strcat(tempstring1, "Yes");
  1120.             AddNameToTail(List2Ptr, tempstring1);
  1121.         } elif (!strcmp(contents[which].name, "FOOT"))
  1122.         {   chunkdesc("Begin footer section");
  1123.  
  1124.             strcpy(tempstring1, "Page type:           ");
  1125.             if (contents[which].DataPtr[0] == 0)
  1126.             {   strcat(tempstring1, "None");
  1127.             } elif (contents[which].DataPtr[0] == 1)
  1128.             {   strcat(tempstring1, "Left");
  1129.             } elif (contents[which].DataPtr[0] == 2)
  1130.             {   strcat(tempstring1, "Right");
  1131.             } elif (contents[which].DataPtr[0] == 3)
  1132.             {   strcat(tempstring1, "Both");
  1133.             } else strcat(tempstring1, "?");
  1134.             AddNameToTail(List2Ptr, tempstring1);
  1135.  
  1136.             strcpy(tempstring1, "First page?          ");
  1137.             if (contents[which].DataPtr[1] == 0)
  1138.             {   strcat(tempstring1, "No");
  1139.             } else strcat(tempstring1, "Yes");
  1140.             AddNameToTail(List2Ptr, tempstring1);
  1141.         } elif (!strcmp(contents[which].name, "PCTS"))
  1142.         {   chunkdesc("Begin picture section");
  1143.  
  1144.             strcpy(tempstring1, "Bitplanes:           ");
  1145.             uvalue = contents[which].DataPtr[0]; // UBYTE
  1146.             stcl_d(tempstring2, uvalue);
  1147.             strcat(tempstring1, tempstring2);
  1148.             AddNameToTail(List2Ptr, tempstring1);
  1149.         } elif (!strcmp(contents[which].name, "PARA"))
  1150.         {   chunkdesc("New paragraph format");
  1151.  
  1152.             strcpy(tempstring1, "Left indent:         ");
  1153.             uvalue = getuword(contents[which].DataPtr); // UWORD
  1154.             stcl_d(tempstring2, uvalue);
  1155.             strcat(tempstring1, tempstring2);
  1156.             strcat(tempstring1, " decipoints");
  1157.             AddNameToTail(List2Ptr, tempstring1);
  1158.  
  1159.             strcpy(tempstring1, "Left margin:         ");
  1160.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  1161.             stcl_d(tempstring2, uvalue);
  1162.             strcat(tempstring1, tempstring2);
  1163.             strcat(tempstring1, " decipoints");
  1164.             AddNameToTail(List2Ptr, tempstring1);
  1165.  
  1166.             strcpy(tempstring1, "Right margin:        ");
  1167.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  1168.             stcl_d(tempstring2, uvalue);
  1169.             strcat(tempstring1, tempstring2);
  1170.             strcat(tempstring1, " decipoints");
  1171.             AddNameToTail(List2Ptr, tempstring1);
  1172.  
  1173.             strcpy(tempstring1, "Line spacing:        ");
  1174.             if (contents[which].DataPtr[6] == 0)
  1175.             {   strcat(tempstring1, "Single");
  1176.             } elif (contents[which].DataPtr[6] == 16)
  1177.             {   strcat(tempstring1, "Double");
  1178.             } else
  1179.             {   strcat(tempstring1, "?");
  1180.             }
  1181.             AddNameToTail(List2Ptr, tempstring1);
  1182.  
  1183.             strcpy(tempstring1, "Justification:       ");
  1184.             if (contents[which].DataPtr[7] == 0)
  1185.             {   strcat(tempstring1, "Left");
  1186.             } elif (contents[which].DataPtr[7] == 1)
  1187.             {   strcat(tempstring1, "Centre");
  1188.             } elif (contents[which].DataPtr[7] == 2)
  1189.             {   strcat(tempstring1, "Right");
  1190.             } elif (contents[which].DataPtr[7] == 3)
  1191.             {   strcat(tempstring1, "Full");
  1192.             } else
  1193.             {   strcat(tempstring1, "?");
  1194.             }
  1195.             AddNameToTail(List2Ptr, tempstring1);
  1196.  
  1197.             strcpy(tempstring1, "Font number:         ");
  1198.             uvalue = contents[which].DataPtr[8]; // UBYTE
  1199.             stcl_d(tempstring2, uvalue);
  1200.             strcat(tempstring1, tempstring2);
  1201.             AddNameToTail(List2Ptr, tempstring1);
  1202.  
  1203.             strcat(tempstring1, " Style:");
  1204.             AddNameToTail(List2Ptr, tempstring1);
  1205.  
  1206.             strcat(tempstring1, " Underlined?         ");
  1207.             if (contents[which].DataPtr[9] & 1)
  1208.             {   strcat(tempstring1, "Yes");
  1209.             } else strcat(tempstring1, "No");
  1210.             AddNameToTail(List2Ptr, tempstring1);
  1211.  
  1212.             strcat(tempstring1, " Bold?               ");
  1213.             if (contents[which].DataPtr[9] & 2)
  1214.             {   strcat(tempstring1, "Yes");
  1215.             } else strcat(tempstring1, "No");
  1216.             AddNameToTail(List2Ptr, tempstring1);
  1217.  
  1218.             strcat(tempstring1, " Italic?             ");
  1219.             if (contents[which].DataPtr[9] & 4)
  1220.             {   strcat(tempstring1, "Yes");
  1221.             } else strcat(tempstring1, "No");
  1222.             AddNameToTail(List2Ptr, tempstring1);
  1223.  
  1224.             strcat(tempstring1, " Extended?           ");
  1225.             if (contents[which].DataPtr[9] & 8)
  1226.             {   strcat(tempstring1, "Yes");
  1227.             } else strcat(tempstring1, "No");
  1228.             AddNameToTail(List2Ptr, tempstring1);
  1229.  
  1230.             strcat(tempstring1, " ColourFont?         ");
  1231.             if (contents[which].DataPtr[9] & 64)
  1232.             {   strcat(tempstring1, "Yes");
  1233.             } else strcat(tempstring1, "No");
  1234.             AddNameToTail(List2Ptr, tempstring1);
  1235.  
  1236.             strcat(tempstring1, " Tagged?             ");
  1237.             if (contents[which].DataPtr[9] & 128)
  1238.             {   strcat(tempstring1, "Yes");
  1239.             } else strcat(tempstring1, "No");
  1240.             AddNameToTail(List2Ptr, tempstring1);
  1241.  
  1242.             strcpy(tempstring1, "Miscellaneous style: ");
  1243.             if (contents[which].DataPtr[10] == 0)
  1244.             {   strcat(tempstring1, "None");
  1245.             } elif (contents[which].DataPtr[10] == 1)
  1246.             {   strcat(tempstring1, "Superscript");
  1247.             } elif (contents[which].DataPtr[10] == 2)
  1248.             {   strcat(tempstring1, "Subscript");
  1249.             } else
  1250.             {   strcat(tempstring1, "?");
  1251.             }
  1252.             AddNameToTail(List2Ptr, tempstring1);
  1253.  
  1254.             strcpy(tempstring1, "Colour:              ");
  1255.             uvalue = contents[which].DataPtr[11]; // UBYTE
  1256.             stcl_d(tempstring2, uvalue);
  1257.             strcat(tempstring1, tempstring2);
  1258.             AddNameToTail(List2Ptr, tempstring1);
  1259.         } elif (!strcmp(contents[which].name, "TABS"))
  1260.         {   chunkdesc("New tab stop types/locations");
  1261.  
  1262.             strcpy(tempstring1, "Position:            ");
  1263.             uvalue = getuword(contents[which].DataPtr); // UWORD
  1264.             stcl_d(tempstring2, uvalue);
  1265.             strcat(tempstring1, tempstring2);
  1266.             strcat(tempstring1, " decipoints");
  1267.             AddNameToTail(List2Ptr, tempstring1);
  1268.  
  1269.             strcpy(tempstring1, "Type:                ");
  1270.             if (contents[which].DataPtr[2] == 0)
  1271.             {   strcat(tempstring1, "Left");
  1272.             } elif (contents[which].DataPtr[2] == 1)
  1273.             {   strcat(tempstring1, "Centre");
  1274.             } elif (contents[which].DataPtr[2] == 2)
  1275.             {   strcat(tempstring1, "Right");
  1276.             } elif (contents[which].DataPtr[2] == 3)
  1277.             {   strcat(tempstring1, "Decimal");
  1278.             } else
  1279.             {   strcat(tempstring1, "?");
  1280.             }
  1281.             AddNameToTail(List2Ptr, tempstring1);
  1282.         } elif (!strcmp(contents[which].name, "PAGE"))
  1283.         {   chunkdesc("Page break");
  1284.         } elif (!strcmp(contents[which].name, "TEXT"))
  1285.         {   chunkdesc("Paragraph text");
  1286.         } elif (!strcmp(contents[which].name, "FSCC"))
  1287.         {   chunkdesc("Font/style/colour change");
  1288.  
  1289.             strcpy(tempstring1, "Location:            ");
  1290.             uvalue = getuword(contents[which].DataPtr); // UWORD
  1291.             stcl_d(tempstring2, uvalue);
  1292.             strcat(tempstring1, tempstring2);
  1293.             AddNameToTail(List2Ptr, tempstring1);
  1294.  
  1295.             strcpy(tempstring1, "Font number:         ");
  1296.             uvalue = contents[which].DataPtr[2]; // UBYTE
  1297.             stcl_d(tempstring2, uvalue);
  1298.             strcat(tempstring1, tempstring2);
  1299.             AddNameToTail(List2Ptr, tempstring1);
  1300.  
  1301.             strcat(tempstring1, " Style:");
  1302.             AddNameToTail(List2Ptr, tempstring1);
  1303.  
  1304.             strcat(tempstring1, " Underlined?         ");
  1305.             if (contents[which].DataPtr[3] & 1)
  1306.             {   strcat(tempstring1, "Yes");
  1307.             } else strcat(tempstring1, "No");
  1308.             AddNameToTail(List2Ptr, tempstring1);
  1309.  
  1310.             strcat(tempstring1, " Bold?               ");
  1311.             if (contents[which].DataPtr[3] & 2)
  1312.             {   strcat(tempstring1, "Yes");
  1313.             } else strcat(tempstring1, "No");
  1314.             AddNameToTail(List2Ptr, tempstring1);
  1315.  
  1316.             strcat(tempstring1, " Italic?             ");
  1317.             if (contents[which].DataPtr[3] & 4)
  1318.             {   strcat(tempstring1, "Yes");
  1319.             } else strcat(tempstring1, "No");
  1320.             AddNameToTail(List2Ptr, tempstring1);
  1321.  
  1322.             strcat(tempstring1, " Extended?           ");
  1323.             if (contents[which].DataPtr[3] & 8)
  1324.             {   strcat(tempstring1, "Yes");
  1325.             } else strcat(tempstring1, "No");
  1326.             AddNameToTail(List2Ptr, tempstring1);
  1327.  
  1328.             strcat(tempstring1, " ColourFont?         ");
  1329.             if (contents[which].DataPtr[3] & 64)
  1330.             {   strcat(tempstring1, "Yes");
  1331.             } else strcat(tempstring1, "No");
  1332.             AddNameToTail(List2Ptr, tempstring1);
  1333.  
  1334.             strcat(tempstring1, " Tagged?             ");
  1335.             if (contents[which].DataPtr[3] & 128)
  1336.             {   strcat(tempstring1, "Yes");
  1337.             } else strcat(tempstring1, "No");
  1338.             AddNameToTail(List2Ptr, tempstring1);
  1339.  
  1340.             strcpy(tempstring1, "Miscellaneous style: ");
  1341.             if (contents[which].DataPtr[4] == 0)
  1342.             {   strcat(tempstring1, "None");
  1343.             } elif (contents[which].DataPtr[4] == 1)
  1344.             {   strcat(tempstring1, "Superscript");
  1345.             } elif (contents[which].DataPtr[4] == 2)
  1346.             {   strcat(tempstring1, "Subscript");
  1347.             } else
  1348.             {   strcat(tempstring1, "?");
  1349.             }
  1350.             AddNameToTail(List2Ptr, tempstring1);
  1351.  
  1352.             strcpy(tempstring1, "Colour:              ");
  1353.             uvalue = contents[which].DataPtr[5]; // UBYTE
  1354.             stcl_d(tempstring2, uvalue);
  1355.             strcat(tempstring1, tempstring2);
  1356.             AddNameToTail(List2Ptr, tempstring1);
  1357.         } elif (!strcmp(contents[which].name, "PINF"))
  1358.         {   chunkdesc("Picture info");
  1359.  
  1360.             strcpy(tempstring1, "Width:               ");
  1361.             uvalue = getuword(contents[which].DataPtr); // UWORD
  1362.             stcl_d(tempstring2, uvalue);
  1363.             strcat(tempstring1, tempstring2);
  1364.             AddNameToTail(List2Ptr, tempstring1);
  1365.  
  1366.             strcpy(tempstring1, "Height:              ");
  1367.             uvalue = getuword(&(contents[which].DataPtr[2])); // UWORD
  1368.             stcl_d(tempstring2, uvalue);
  1369.             strcat(tempstring1, tempstring2);
  1370.             AddNameToTail(List2Ptr, tempstring1);
  1371.  
  1372.             strcpy(tempstring1, "Page:                ");
  1373.             uvalue = getuword(&(contents[which].DataPtr[4])); // UWORD
  1374.             stcl_d(tempstring2, uvalue);
  1375.             strcat(tempstring1, tempstring2);
  1376.             AddNameToTail(List2Ptr, tempstring1);
  1377.  
  1378.             strcpy(tempstring1, "X-position:          ");
  1379.             uvalue = getuword(&(contents[which].DataPtr[6])); // UWORD
  1380.             stcl_d(tempstring2, uvalue);
  1381.             strcat(tempstring1, tempstring2);
  1382.             strcat(tempstring1, " decipoints");
  1383.             AddNameToTail(List2Ptr, tempstring1);
  1384.  
  1385.             strcpy(tempstring1, "Y-position:          ");
  1386.             uvalue = getuword(&(contents[which].DataPtr[8])); // UWORD
  1387.             stcl_d(tempstring2, uvalue);
  1388.             strcat(tempstring1, tempstring2);
  1389.             strcat(tempstring1, " decipoints");
  1390.             AddNameToTail(List2Ptr, tempstring1);
  1391.  
  1392.             strcpy(tempstring1, "Masking:            ");
  1393.             if (contents[which].DataPtr[10] == 0)
  1394.             {   strcat(tempstring1, "0 (Opaque)");
  1395.             } elif (contents[which].DataPtr[10] == 1)
  1396.             {   strcat(tempstring1, "1 (Mask plane)");
  1397.             } elif (contents[which].DataPtr[10] == 2)
  1398.             {   strcat(tempstring1, "2 (Transparent colour)");
  1399.             } elif (contents[which].DataPtr[10] == 3)
  1400.             {   strcat(tempstring1, "3 (Lasso)");
  1401.             } else strcat(tempstring1, "?");
  1402.             AddNameToTail(List2Ptr, tempstring1);
  1403.  
  1404.             strcpy(tempstring1, "Compression:        ");
  1405.             if (contents[which].DataPtr[11] == 0)
  1406.             {   strcat(tempstring1, "None");
  1407.             } elif (contents[which].DataPtr[11] == 1)
  1408.             {   strcat(tempstring1, "Byte run encoding");
  1409.             } else strcat(tempstring1, "?");
  1410.             AddNameToTail(List2Ptr, tempstring1);
  1411.  
  1412.             strcpy(tempstring1, "Transparent colour: ");
  1413.             if (contents[which].DataPtr[12] != 2
  1414.              && contents[which].DataPtr[12] != 3)
  1415.             {   strcat(tempstring1, "n/a");
  1416.             } else
  1417.             {   stcl_d(tempstring2, (256 * contents[which].DataPtr[12])
  1418.                                   +        contents[which].DataPtr[13]);
  1419.                 strcat(tempstring1, tempstring2);
  1420.             }
  1421.             AddNameToTail(List2Ptr, tempstring1);
  1422.     }   }
  1423.     elif (!strcmp(queryform, "AIFF"))
  1424.     {   if (!strcmp(contents[which].name, "MIDI"))
  1425.         {   chunkdesc("Stores MIDI data");
  1426.         } elif (!strcmp(contents[which].name, "MARK"))
  1427.         {   chunkdesc("Points to positions in the sound data");
  1428.  
  1429.             strcpy(tempstring1, "Markers:             ");
  1430.             svalue = getsword(contents[which].DataPtr);
  1431.             stcl_d(tempstring2, svalue);
  1432.             strcat(tempstring1, tempstring2);
  1433.             if (svalue < 0)
  1434.             {   strcat(tempstring1, "!");
  1435.             }
  1436.             AddNameToTail(List2Ptr, tempstring1);
  1437.             markers = svalue;
  1438.             if (markers > 0)
  1439.             {   currentpos = 2;
  1440.                 for (i = 1; i <= markers; i++)
  1441.                 {   strcpy(tempstring1, "Marker ");
  1442.                     stcl_d(tempstring2, i);
  1443.                     strcat(tempstring1, tempstring2);
  1444.                     strcat(tempstring1, ":");
  1445.                     AddNameToTail(List2Ptr, tempstring1);
  1446.  
  1447.                     strcpy(tempstring1, " ID:                 ");
  1448.                     svalue = getsword(&(contents[which].name[currentpos]));
  1449.                     stcl_d(tempstring2, svalue);
  1450.                     strcat(tempstring1, tempstring2);
  1451.                     if (svalue < 1)
  1452.                     {   strcat(tempstring1, "!");
  1453.                     }
  1454.                     AddNameToTail(List2Ptr, tempstring1);
  1455.                     currentpos += 2;
  1456.  
  1457.                     strcpy(tempstring1, " Position:           ");
  1458.                     uvalue = getulong(&(contents[which].name[currentpos]));
  1459.                     stcl_d(tempstring2, uvalue);
  1460.                     strcat(tempstring1, tempstring2);
  1461.                     AddNameToTail(List2Ptr, tempstring1);
  1462.                     currentpos += 4;
  1463.  
  1464.                     strcpy(tempstring1, " Name:               ");
  1465.                     uvalue = contents[which].name[currentpos++];
  1466.                     // the number of characters in the string
  1467.                     if (uvalue < MEDFIELD)
  1468.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  1469.                     } else
  1470.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  1471.                     }
  1472.                     AddNameToTail(List2Ptr, tempstring1);
  1473.                     currentpos += uvalue;
  1474.                     if (uvalue % 2)
  1475.                     {   currentpos++; // skip pad byte, if appropriate
  1476.         }   }   }   }
  1477.         elif (!strcmp(contents[which].name, "AESD"))
  1478.         {   chunkdesc("Pertinent to autio recording devices");
  1479.         } elif (!strcmp(contents[which].name, "COMT"))
  1480.         {   chunkdesc("Stores comments");
  1481.  
  1482.             strcpy(tempstring1, "Comments:            ");
  1483.             svalue = getsword(contents[which].DataPtr);
  1484.             stcl_d(tempstring2, svalue);
  1485.             strcat(tempstring1, tempstring2);
  1486.             if (svalue < 0)
  1487.             {   strcat(tempstring1, "!");
  1488.             }
  1489.             AddNameToTail(List2Ptr, tempstring1);
  1490.  
  1491.             // we could have a 'comments' variable, but we just reuse
  1492.             // the 'markers' variable.
  1493.             markers = svalue;
  1494.             if (markers > 0)
  1495.             {   currentpos = 2;
  1496.                 for (i = 1; i <= markers; i++)
  1497.                 {   strcpy(tempstring1, "Comment ");
  1498.                     stcl_d(tempstring2, i);
  1499.                     strcat(tempstring1, tempstring2);
  1500.                     strcat(tempstring1, ":");
  1501.                     AddNameToTail(List2Ptr, tempstring1);
  1502.  
  1503.                     strcpy(tempstring1, " Created on:         ");
  1504.                     uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  1505.                     DateTime.dat_Stamp.ds_Days   =   uvalue / 86400;             // days since 1/1/78
  1506.                     DateTime.dat_Stamp.ds_Minute =  (uvalue % 86400) / 60;       // minutes in day
  1507.                     DateTime.dat_Stamp.ds_Tick   = ((uvalue % 86400) % 60) * 50; // ticks in minute
  1508.                     DateTime.dat_Format          = FORMAT_DOS;
  1509.                     DateTime.dat_Flags           = DTF_SUBST;
  1510.                     DateTime.dat_StrDay          = weekdaystring;
  1511.                     DateTime.dat_StrDate         = datestring;
  1512.                     DateTime.dat_StrTime         = timestring;
  1513.                     if (!DateToStr(&DateTime))
  1514.                     {   rq("DateToStr() failed!");
  1515.                     }
  1516.                     strcat(tempstring1, timestring);
  1517.                     strcat(tempstring1, " ");
  1518.                     strcat(tempstring1, weekdaystring);
  1519.                     strcat(tempstring1, " ");
  1520.                     strcat(tempstring1, datestring);
  1521.                     AddNameToTail(List2Ptr, tempstring1);
  1522.                     currentpos += 4;
  1523.  
  1524.                     strcpy(tempstring1, " Marker ID:          ");
  1525.                     svalue = getsword(&(contents[which].DataPtr[currentpos]));
  1526.                     stcl_d(tempstring2, svalue);
  1527.                     strcat(tempstring1, tempstring2);
  1528.                     if (svalue < 1)
  1529.                     {    strcat(tempstring1, "!");
  1530.                     }
  1531.                     AddNameToTail(List2Ptr, tempstring1);
  1532.                     currentpos += 2;
  1533.  
  1534.                     strcpy(tempstring1, " Comment:            ");
  1535.                     uvalue = getuword(&(contents[which].DataPtr[currentpos]));
  1536.                     // the number of characters in the string
  1537.                     currentpos += 2;
  1538.                     if (uvalue < MEDFIELD)
  1539.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), uvalue);
  1540.                     } else
  1541.                     {   strncat(tempstring1, &(contents[which].name[currentpos]), MEDFIELD);
  1542.                     }
  1543.                     AddNameToTail(List2Ptr, tempstring1);
  1544.                     currentpos += uvalue;
  1545.                     if (uvalue % 2)
  1546.                     {   currentpos++; // skip pad byte, if appropriate
  1547.         }   }   }   }
  1548.         elif (!strcmp(contents[which].name, "COMM"))
  1549.         {   chunkdesc("Fundamental parameters for the sampled sound");
  1550.  
  1551.             strcpy(tempstring1, "Channels:            ");
  1552.             svalue = getsword(contents[which].DataPtr);
  1553.             stcl_d(tempstring2, svalue);
  1554.             strcat(tempstring1, tempstring2);
  1555.             if (svalue == 1)
  1556.             {   strcat(tempstring1, " (mono)");
  1557.             } elif (svalue == 2)
  1558.             {   strcat(tempstring1, " (stereo)");
  1559.             } elif (svalue > 2)
  1560.             {   strcat(tempstring1, " (surround)");
  1561.             }
  1562.             AddNameToTail(List2Ptr, tempstring1);
  1563.  
  1564.             strcpy(tempstring1, "Sample frames:       ");
  1565.             uvalue = getulong(&(contents[which].DataPtr[2]));
  1566.             stcl_d(tempstring2, uvalue);
  1567.             strcat(tempstring1, tempstring2);
  1568.             AddNameToTail(List2Ptr, tempstring1);
  1569.  
  1570.             strcpy(tempstring1, "Sample quality:      ");
  1571.             svalue = getsword(&(contents[which].DataPtr[6]));
  1572.             stcl_d(tempstring2, svalue);
  1573.             strcat(tempstring1, tempstring2);
  1574.             strcat(tempstring1, "-bit");
  1575.             AddNameToTail(List2Ptr, tempstring1);
  1576.  
  1577.             /* This is an 80-bit IEEE 754 Apple-style (SANE) floating
  1578.             point number (not yet implemented):
  1579.                  79 Sign
  1580.               64:78 Exponent
  1581.                0:63 Mantissa */
  1582.             strcpy(tempstring1, "Playback rate:       -");
  1583.             AddNameToTail(List2Ptr, tempstring1);
  1584.         } elif (!strcmp(contents[which].name, "APPL"))
  1585.         {   chunkdesc("Application-specific data");
  1586.  
  1587.             strcpy(tempstring1, "Application:         ");
  1588.             strcat(tempstring1, contents[which].DataPtr);
  1589.             if (!strcmp(tempstring1, "pdos"))
  1590.             {   strcat(tempstring1, " (Apple II)");
  1591.             }
  1592.             AddNameToTail(List2Ptr, tempstring1);
  1593.         } elif (!strcmp(contents[which].name, "SSND"))
  1594.         {   chunkdesc("The actual sample frames");
  1595.  
  1596.             strcpy(tempstring1, "Offset:              ");
  1597.             uvalue = getulong(contents[which].DataPtr);
  1598.             stcl_d(tempstring2, uvalue);
  1599.             strcat(tempstring1, tempstring2);
  1600.             AddNameToTail(List2Ptr, tempstring1);
  1601.  
  1602.             strcpy(tempstring1, "Block size:          ");
  1603.             uvalue = getulong(&(contents[which].DataPtr[4]));
  1604.             stcl_d(tempstring2, uvalue);
  1605.             strcat(tempstring1, tempstring2);
  1606.             AddNameToTail(List2Ptr, tempstring1);
  1607.         } elif (!strcmp(contents[which].name, "INST"))
  1608.         {   chunkdesc("The actual sample frames");
  1609.  
  1610.             strcpy(tempstring1, "Base note:           ");
  1611.             svalue = getsbyte(&(contents[which].DataPtr[0]));
  1612.             stcl_d(tempstring2, svalue);
  1613.             strcat(tempstring1, tempstring2);
  1614.             if (svalue < 0 || svalue > 127)
  1615.                 strcat(tempstring1, "!");
  1616.             AddNameToTail(List2Ptr, tempstring1);
  1617.  
  1618.             strcpy(tempstring1, "Detune:              ");
  1619.             svalue = getsbyte(&(contents[which].DataPtr[1]));
  1620.             stcl_d(tempstring2, svalue);
  1621.             strcat(tempstring1, tempstring2);
  1622.             if (svalue < -50 || svalue > 50)
  1623.                 strcat(tempstring1, "!");
  1624.             AddNameToTail(List2Ptr, tempstring1);
  1625.  
  1626.             strcpy(tempstring1, "Low note:            ");
  1627.             svalue = getsbyte(&(contents[which].DataPtr[2]));
  1628.             stcl_d(tempstring2, svalue);
  1629.             strcat(tempstring1, tempstring2);
  1630.             if (svalue < 0 || svalue > 127)
  1631.                 strcat(tempstring1, "!");
  1632.             AddNameToTail(List2Ptr, tempstring1);
  1633.  
  1634.             strcpy(tempstring1, "High note:           ");
  1635.             svalue = getsbyte(&(contents[which].DataPtr[3]));
  1636.             stcl_d(tempstring2, svalue);
  1637.             strcat(tempstring1, tempstring2);
  1638.             if (svalue < 0 || svalue > 127)
  1639.                 strcat(tempstring1, "!");
  1640.             AddNameToTail(List2Ptr, tempstring1);
  1641.  
  1642.             strcpy(tempstring1, "Low velocity:        ");
  1643.             svalue = getsbyte(&(contents[which].DataPtr[4]));
  1644.             stcl_d(tempstring2, svalue);
  1645.             strcat(tempstring1, tempstring2);
  1646.             if (svalue < 1 || svalue > 127)
  1647.                 strcat(tempstring1, "!");
  1648.             AddNameToTail(List2Ptr, tempstring1);
  1649.  
  1650.             strcpy(tempstring1, "High velocity:       ");
  1651.             svalue = getsbyte(&(contents[which].DataPtr[5]));
  1652.             stcl_d(tempstring2, svalue);
  1653.             strcat(tempstring1, tempstring2);
  1654.             if (svalue < 1 || svalue > 127)
  1655.                 strcat(tempstring1, "!");
  1656.             AddNameToTail(List2Ptr, tempstring1);
  1657.  
  1658.             strcpy(tempstring1, "Gain:                ");
  1659.             svalue = getsword(&(contents[which].DataPtr[6]));
  1660.             stcl_d(tempstring2, svalue);
  1661.             strcat(tempstring1, tempstring2);
  1662.             AddNameToTail(List2Ptr, tempstring1);
  1663.  
  1664.             AddNameToTail(List2Ptr, "Sustain loop:");
  1665.  
  1666.             svalue = getsword(&(contents[which].DataPtr[8]));
  1667.             if (svalue == 0)
  1668.             {   strcpy(tempstring1, " No looping");
  1669.             } elif (svalue == 1)
  1670.             {   strcpy(tempstring1, " Forwards looping");
  1671.             } elif (svalue == 2)
  1672.             {   strcpy(tempstring1, " Forwards/backwards looping");
  1673.             } else
  1674.             {   strcpy(tempstring1, " ?");
  1675.             }
  1676.             AddNameToTail(List2Ptr, tempstring1);
  1677.             strcpy(tempstring1, " Begin loop:         ");
  1678.             svalue = getsword(&(contents[which].DataPtr[10]));
  1679.             stcl_d(tempstring1, svalue);
  1680.             AddNameToTail(List2Ptr, tempstring1);
  1681.             strcpy(tempstring1, " End loop:           ");
  1682.             svalue = getsword(&(contents[which].DataPtr[12]));
  1683.             stcl_d(tempstring1, svalue);
  1684.             AddNameToTail(List2Ptr, tempstring1);
  1685.  
  1686.             strcpy(tempstring1, "Release loop:        ");
  1687.  
  1688.             svalue = getsword(&(contents[which].DataPtr[14]));
  1689.             if (svalue == 0)
  1690.             {   strcpy(tempstring1, " No looping");
  1691.             } elif (svalue == 1)
  1692.             {   strcpy(tempstring1, " Forwards looping");
  1693.             } elif (svalue == 2)
  1694.             {   strcpy(tempstring1, " Forwards/backwards looping");
  1695.             } else
  1696.             {   strcpy(tempstring1, " ?");
  1697.             }
  1698.             AddNameToTail(List2Ptr, tempstring1);
  1699.             strcpy(tempstring1, " Begin loop:         ");
  1700.             svalue = getsword(&(contents[which].DataPtr[16]));
  1701.             stcl_d(tempstring1, svalue);
  1702.             AddNameToTail(List2Ptr, tempstring1);
  1703.             strcpy(tempstring1, " End loop:           ");
  1704.             svalue = getsword(&(contents[which].DataPtr[18]));
  1705.             stcl_d(tempstring1, svalue);
  1706.             AddNameToTail(List2Ptr, tempstring1);
  1707.     }   }
  1708.     elif (!strcmp(queryform, "8SVX"))
  1709.     {   if (!strcmp(contents[which].name, "ATAK"))
  1710.         {   chunkdesc("Gives attack amplitude contour (envelope)");
  1711.         } elif (!strcmp(contents[which].name, "RLSE"))
  1712.         {   chunkdesc("Gives release amplitude contour (envelope)");
  1713.         } elif (!strcmp(contents[which].name, "BODY"))
  1714.         {   chunkdesc("Sound data chunk");
  1715.         } elif (!strcmp(contents[which].name, "FADE"))
  1716.         {   chunkdesc("Fade away to silence");
  1717.  
  1718.             strcpy(tempstring1, "Fade start:          ");
  1719.             uvalue = getulong(contents[which].DataPtr);
  1720.             stcl_d(tempstring2, uvalue);
  1721.             strcat(tempstring1, tempstring2);
  1722.             AddNameToTail(List2Ptr, tempstring1);
  1723.         } elif (!strcmp(contents[which].name, "SEQN"))
  1724.         {   chunkdesc("Multiple loop sequencing");
  1725.  
  1726.             currentpos = 0;
  1727.             while (currentpos < contents[which].bytes)
  1728.             {   strcpy(tempstring1, "Loop start:          ");
  1729.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  1730.                 stcl_d(tempstring2, uvalue);
  1731.                 strcat(tempstring1, tempstring2);
  1732.                 if (uvalue % 4)
  1733.                 {   strcat(tempstring1, "!");
  1734.                 }
  1735.                 AddNameToTail(List2Ptr, tempstring1);
  1736.                 currentpos += 4;
  1737.  
  1738.                 strcpy(tempstring1, "Loop end:            ");
  1739.                 uvalue = getulong(&(contents[which].DataPtr[currentpos]));
  1740.                 stcl_d(tempstring2, uvalue);
  1741.                 strcat(tempstring1, tempstring2);
  1742.                 if (uvalue % 4)
  1743.                 {   strcat(tempstring1, "!");
  1744.                 }
  1745.                 AddNameToTail(List2Ptr, tempstring1);
  1746.                 currentpos += 4;
  1747.         }   }
  1748.         elif (!strcmp(contents[which].name, "CHAN"))
  1749.         {   chunkdesc("Specified channel, or combination of channels");
  1750.             strcpy(tempstring1, "Channel:             ");
  1751.             svalue = getslong(contents[which].DataPtr);
  1752.             if (svalue == 2)
  1753.             {   strcat(tempstring1, "Left");
  1754.             } elif (svalue == 4)
  1755.             {   strcat(tempstring1, "Right");
  1756.             } elif (svalue == 6)
  1757.             {   strcat(tempstring1, "Stereo (both)");
  1758.             } else strcat(tempstring1, "?");
  1759.             AddNameToTail(List2Ptr, tempstring1);
  1760.         } elif (!strcmp(contents[which].name, "PAN "))
  1761.         {   chunkdesc("Stereo sound using a single array of data");
  1762.             strcpy(tempstring1, "Sound position:      ");
  1763.             svalue = getslong(contents[which].DataPtr);
  1764.             stcl_d(tempstring2, svalue);
  1765.             strcat(tempstring1, tempstring2);
  1766.             strcat(tempstring1, "/65536 ");
  1767.             if (svalue < 32768)
  1768.             {    strcat(tempstring1, "(left)");
  1769.             } elif (svalue > 32678)
  1770.             {    strcat(tempstring1, "(right)");
  1771.             } else
  1772.             {    // assert(svalue == 32678);
  1773.                  strcat(tempstring1, "(centre)");
  1774.             }
  1775.             AddNameToTail(List2Ptr, tempstring1);
  1776.         } elif (!strcmp(contents[which].name, "VHDR"))
  1777.         {   chunkdesc("Playback parameters for the sampled waveforms");
  1778.             strcpy(tempstring1, "1-shot samples:      ");
  1779.             uvalue = getulong(contents[which].DataPtr);
  1780.             stcl_d(tempstring2, uvalue);
  1781.             strcat(tempstring1, tempstring2);
  1782.             AddNameToTail(List2Ptr, tempstring1);
  1783.  
  1784.             strcpy(tempstring1, "Repeat samples:      ");
  1785.             uvalue = getulong(&(contents[which].DataPtr[4]));
  1786.             stcl_d(tempstring2, uvalue);
  1787.             strcat(tempstring1, tempstring2);
  1788.             AddNameToTail(List2Ptr, tempstring1);
  1789.  
  1790.             strcpy(tempstring1, "Samples per cycle:   ");
  1791.             uvalue = getulong(&(contents[which].DataPtr[8]));
  1792.             stcl_d(tempstring2, uvalue);
  1793.             strcat(tempstring1, tempstring2);
  1794.             AddNameToTail(List2Ptr, tempstring1);
  1795.  
  1796.             strcpy(tempstring1, "Sampling rate:       ");
  1797.             uvalue = getuword(&(contents[which].DataPtr[12]));
  1798.             stcl_d(tempstring2, uvalue);
  1799.             strcat(tempstring1, tempstring2);
  1800.             AddNameToTail(List2Ptr, tempstring1);
  1801.  
  1802.             strcpy(tempstring1, "Octaves:             ");
  1803.             uvalue = contents[which].DataPtr[14]; // UBYTE
  1804.             stcl_d(tempstring2, uvalue);
  1805.             strcat(tempstring1, tempstring2);
  1806.             AddNameToTail(List2Ptr, tempstring1);
  1807.  
  1808.             strcpy(tempstring1, "Compression:         "); // UBYTE
  1809.             if (contents[which].DataPtr[15] == 0)
  1810.             {   strcat(tempstring1, "None");
  1811.             } elif (contents[which].DataPtr[15] == 1)
  1812.             {   strcat(tempstring1, "Fibonacci-delta encoding");
  1813.             } else strcat(tempstring1, "?");
  1814.             AddNameToTail(List2Ptr, tempstring1);
  1815.  
  1816.             strcpy(tempstring1, "Volume:              ");
  1817.             svalue = getslong(&(contents[which].DataPtr[16]));
  1818.             svalue /= 1024; // LONG (Fixed)
  1819.             stcl_d(tempstring2, svalue);
  1820.             strcat(tempstring1, tempstring2);
  1821.             strcat(tempstring1, "/64");
  1822.             AddNameToTail(List2Ptr, tempstring1);
  1823.     }   }
  1824.     elif (!strcmp(queryform, "ILBM"))
  1825.     {   if (!strcmp(contents[which].name, "CAMG"))
  1826.         {   chunkdesc("Specifies the Amiga display mode of a picture");
  1827.  
  1828.             strcpy(tempstring1, "ModeID:             $");
  1829.             uvalue = getulong(contents[which].DataPtr);
  1830.             stcl_h(tempstring2, uvalue);
  1831.             strcat(tempstring1, tempstring2);
  1832.             AddNameToTail(List2Ptr, tempstring1);
  1833.         } elif (!strcmp(contents[which].name, "DPI "))
  1834.         {   chunkdesc("Dots per inch");
  1835.  
  1836.             strcpy(tempstring1, "Dots per inch:      ");
  1837.             // There are 20 characters in the first column.
  1838.             uvalue = getuword(contents[which].DataPtr);
  1839.             stcl_h(tempstring2, uvalue);
  1840.             strcat(tempstring1, tempstring2);
  1841.             strcat(tempstring1, "x");
  1842.             uvalue = getuword(&(contents[which].DataPtr[2]));
  1843.             stcl_h(tempstring2, uvalue);
  1844.             strcat(tempstring1, tempstring2);
  1845.             AddNameToTail(List2Ptr, tempstring1);
  1846.         } elif (!strcmp(contents[which].name, "CMAP"))
  1847.         {   chunkdesc("Colour map data");
  1848.         } elif (!strcmp(contents[which].name, "BODY"))
  1849.         {   chunkdesc("Image data chunk");
  1850.         } elif (!strcmp(contents[which].name, "EPSF"))
  1851.         {   chunkdesc("Encapsulated PostScript representation of image");
  1852.  
  1853.             strcpy(tempstring1, "Left X:             ");
  1854.             svalue = getsword(contents[which].DataPtr);
  1855.             stcl_d(tempstring2, svalue);
  1856.             strcat(tempstring1, tempstring2);
  1857.             AddNameToTail(List2Ptr, tempstring1);
  1858.  
  1859.             strcpy(tempstring1, "Top Y:              ");
  1860.             svalue = getsword(&(contents[which].DataPtr[2]));
  1861.             stcl_d(tempstring2, svalue);
  1862.             strcat(tempstring1, tempstring2);
  1863.             AddNameToTail(List2Ptr, tempstring1);
  1864.  
  1865.             strcpy(tempstring1, "Right X:            ");
  1866.             svalue = getsword(&(contents[which].DataPtr[4]));
  1867.             stcl_d(tempstring2, svalue);
  1868.             strcat(tempstring1, tempstring2);
  1869.             AddNameToTail(List2Ptr, tempstring1);
  1870.  
  1871.             strcpy(tempstring1, "Bottom Y:           ");
  1872.             svalue = getsword(&(contents[which].DataPtr[6]));
  1873.             stcl_d(tempstring2, svalue);
  1874.             strcat(tempstring1, tempstring2);
  1875.             AddNameToTail(List2Ptr, tempstring1);
  1876.         } elif (!strcmp(contents[which].name, "DEST"))
  1877.         {   chunkdesc("Scatter bitplanes into a deeper destination image");
  1878.  
  1879.             strcpy(tempstring1, "Source bitplanes:   ");
  1880.             stcl_d(tempstring2, contents[which].DataPtr[0]);
  1881.             strcat(tempstring1, tempstring2);
  1882.             AddNameToTail(List2Ptr, tempstring1);
  1883.  
  1884.             // next (1) is a pad byte.
  1885.  
  1886.             strcpy(tempstring1, "PlanePick:          %"); // UWORD
  1887.             binarize(contents[which].DataPtr[2]);
  1888.             binarize(contents[which].DataPtr[3]);
  1889.             AddNameToTail(List2Ptr, tempstring1);
  1890.  
  1891.             strcpy(tempstring1, "PlaneOnOff:         %"); // UWORD
  1892.             binarize(contents[which].DataPtr[4]);
  1893.             binarize(contents[which].DataPtr[5]);
  1894.             AddNameToTail(List2Ptr, tempstring1);
  1895.  
  1896.             strcpy(tempstring1, "PlaneMask:          %"); // UWORD
  1897.             binarize(contents[which].DataPtr[6]);
  1898.             binarize(contents[which].DataPtr[7]);
  1899.             AddNameToTail(List2Ptr, tempstring1);
  1900.         } elif (!strcmp(contents[which].name, "GRAB"))
  1901.         {   chunkdesc("Locates a hotspot, when used as a pointer or brush");
  1902.  
  1903.             strcpy(tempstring1, "Hotspot:            ");
  1904.             svalue = getsword(contents[which].DataPtr);
  1905.             stcl_h(tempstring2, svalue);
  1906.             strcat(tempstring1, tempstring2);
  1907.             strcat(tempstring1, ",");
  1908.             svalue = getsword(&(contents[which].DataPtr[2]));
  1909.             stcl_h(tempstring2, svalue);
  1910.             strcat(tempstring1, tempstring2);
  1911.             AddNameToTail(List2Ptr, tempstring1);
  1912.         } elif (!strcmp(contents[which].name, "SPRT"))
  1913.         {   chunkdesc("This image is intended as a sprite");
  1914.  
  1915.             strcpy(tempstring1, "Precedence:         ");
  1916.             uvalue = getuword(contents[which].DataPtr);
  1917.  
  1918.             stcl_h(tempstring2, uvalue);
  1919.             strcat(tempstring1, tempstring2);
  1920.             AddNameToTail(List2Ptr, tempstring1);
  1921.         } elif (!strcmp(contents[which].name, "BMHD"))
  1922.         {   /* UWORD w, h;               0-1, 2-3
  1923.             WORD  x, y;                  4-5, 6-7
  1924.             UBYTE nPlanes;               8
  1925.             UBYTE Masking;               9
  1926.             UBYTE Compression;           10
  1927.             UBYTE pad;                   11
  1928.             UWORD transparentColour;     12-13
  1929.             UBYTE xAspect, yAspect;      14, 15
  1930.             WORD  pageWidth, pageHeight; 16-17, 18-19 */
  1931.  
  1932.             chunkdesc("Data necessary to understand the BODY chunk");
  1933.             strcpy(tempstring1, "Image size:         ");
  1934.             stcl_d(tempstring2, (256 * contents[which].DataPtr[0])
  1935.                               +        contents[which].DataPtr[1]); // UWORD
  1936.             strcat(tempstring1, tempstring2);
  1937.             strcat(tempstring1, "x");
  1938.             stcl_d(tempstring2, (256 * contents[which].DataPtr[2])
  1939.                               +        contents[which].DataPtr[3]); // UWORD
  1940.             strcat(tempstring1, tempstring2);
  1941.             AddNameToTail(List2Ptr, tempstring1);
  1942.  
  1943.             strcpy(tempstring1, "Position:           ");
  1944.             stcl_d(tempstring2, (256 * contents[which].DataPtr[4])
  1945.                               +        contents[which].DataPtr[5]); // WORD
  1946.             strcat(tempstring1, tempstring2);
  1947.             strcat(tempstring1, ",");
  1948.             stcl_d(tempstring2, (256 * contents[which].DataPtr[6])
  1949.                               +        contents[which].DataPtr[7]); // WORD
  1950.             strcat(tempstring1, tempstring2);
  1951.             AddNameToTail(List2Ptr, tempstring1);
  1952.  
  1953.             strcpy(tempstring1, "Bitplanes:          ");
  1954.             stcl_d(tempstring2, (LONG) contents[which].DataPtr[8]);
  1955.             strcat(tempstring1, tempstring2);
  1956.             AddNameToTail(List2Ptr, tempstring1);
  1957.             // tell number of colours to user?
  1958.  
  1959.             strcpy(tempstring1, "Masking:            ");
  1960.             if (contents[which].DataPtr[9] == 0)
  1961.             {   strcat(tempstring1, "0 (Opaque)");
  1962.             } elif (contents[which].DataPtr[9] == 1)
  1963.             {   strcat(tempstring1, "1 (Mask plane)");
  1964.             } elif (contents[which].DataPtr[9] == 2)
  1965.             {   strcat(tempstring1, "2 (Transparent colour)");
  1966.             } elif (contents[which].DataPtr[9] == 3)
  1967.             {   strcat(tempstring1, "3 (Lasso)");
  1968.             } else strcat(tempstring1, "?");
  1969.             AddNameToTail(List2Ptr, tempstring1);
  1970.  
  1971.             strcpy(tempstring1, "Compression:        ");
  1972.             if (contents[which].DataPtr[10] == 0)
  1973.             {   strcat(tempstring1, "None");
  1974.             } elif (contents[which].DataPtr[10] == 1)
  1975.             {   strcat(tempstring1, "Byte run encoding");
  1976.             } else strcat(tempstring1, "?");
  1977.             AddNameToTail(List2Ptr, tempstring1);
  1978.  
  1979.             // Next (11) is a pad byte.
  1980.  
  1981.             strcpy(tempstring1, "Transparent colour: ");
  1982.             if (contents[which].DataPtr[9] != 2
  1983.              && contents[which].DataPtr[9] != 3)
  1984.             {   strcat(tempstring1, "n/a");
  1985.             } else
  1986.             {   stcl_d(tempstring2, (256 * contents[which].DataPtr[12])
  1987.                                   +        contents[which].DataPtr[13]);
  1988.                 strcat(tempstring1, tempstring2);
  1989.             }
  1990.             AddNameToTail(List2Ptr, tempstring1);
  1991.  
  1992.             strcpy(tempstring1, "Aspect ratio:       ");
  1993.             stcl_d(tempstring2, (UBYTE) contents[which].DataPtr[14]);
  1994.             strcat(tempstring1, tempstring2);
  1995.             strcat(tempstring1, ":");
  1996.             stcl_d(tempstring2, (UBYTE) contents[which].DataPtr[15]);
  1997.             strcat(tempstring1, tempstring2);
  1998.             AddNameToTail(List2Ptr, tempstring1);
  1999.  
  2000.             strcpy(tempstring1, "Page size:          ");
  2001.             stcl_d(tempstring2, (256 * contents[which].DataPtr[16])
  2002.                               +        contents[which].DataPtr[17]); // WORD
  2003.             strcat(tempstring1, tempstring2);
  2004.             strcat(tempstring1, "x");
  2005.             stcl_d(tempstring2, (256 * contents[which].DataPtr[18])
  2006.                               +        contents[which].DataPtr[19]); // WORD
  2007.             strcat(tempstring1, tempstring2);
  2008.             AddNameToTail(List2Ptr, tempstring1);
  2009.     }   }
  2010.     GT_SetGadgetAttrs
  2011.     (   LV61_List2,
  2012.         MainWindowPtr,
  2013.         NULL,
  2014.         GTLV_Labels, List2Ptr,
  2015.         TAG_DONE
  2016.     );
  2017.     if (!known)
  2018.     {   chunkdesc("?");
  2019. }   }
  2020.  
  2021. MODULE void chunkdesc(STRPTR desc)
  2022. {   GT_SetGadgetAttrs
  2023.     (   TE61_ChunkDesc,
  2024.         MainWindowPtr,
  2025.         NULL,
  2026.         GTTX_Text, desc,
  2027.         TAG_DONE
  2028.     );
  2029.     known = TRUE;
  2030. }
  2031.  
  2032. MODULE void binarize(UBYTE data)
  2033. {   ULONG i;
  2034.  
  2035.     for (i = 7; i >= 0; i--)
  2036.     {   if (data & (1 << i))
  2037.         {   strcat(tempstring1, "1");
  2038.         } else strcat(tempstring1, "0");
  2039. }   }
  2040.  
  2041. MODULE ULONG getulong(UBYTE* start)
  2042. {   return (ULONG) ((16777216 * *(start    ))
  2043.                   + (   65536 * *(start + 1))
  2044.                   + (     256 * *(start + 2))
  2045.                   +             *(start + 3));
  2046. }
  2047. MODULE SLONG getslong(UBYTE* start)
  2048. {   return (SLONG) ((16777216 * *(start    ))
  2049.                   + (   65536 * *(start + 1))
  2050.                   + (     256 * *(start + 2))
  2051.                   +             *(start + 3));
  2052. }
  2053. MODULE ULONG getuword(UBYTE* start)
  2054. {   return (ULONG) ((     256 * *(start    ))
  2055.                   +             *(start + 1));
  2056. }
  2057. MODULE SLONG getsword(UBYTE* start)
  2058. {   return (SLONG) ((     256 * *(start    ))
  2059.                   +             *(start + 1));
  2060. }
  2061. MODULE SLONG getsbyte(UBYTE* start)
  2062. {   return (SBYTE) (*start);
  2063. }
  2064.  
  2065. MODULE struct List* clearlist(struct Gadget* GadgetPtr, struct List* ListPtr)
  2066. {   // At the conclusion of this, we have an empty list, which is attached
  2067.     // to and displayed by the listview.
  2068.  
  2069.     GT_SetGadgetAttrs
  2070.     (   GadgetPtr,
  2071.         MainWindowPtr,
  2072.         NULL,
  2073.         GTLV_Labels, (UWORD) ~0,
  2074.         TAG_DONE
  2075.     );
  2076.     if (ListPtr)
  2077.     {   FreeNameNodes(ListPtr);
  2078.         FreeMem(ListPtr, sizeof(struct List));
  2079.         // ListPtr = NULL;
  2080.     }
  2081.     if (!(ListPtr = AllocMem(sizeof(struct List), MEMF_CLEAR)))
  2082.         rq("Out of memory!");
  2083.     NewList(ListPtr);
  2084.     GT_SetGadgetAttrs
  2085.     (   GadgetPtr,
  2086.         MainWindowPtr,
  2087.         NULL,
  2088.         GTLV_Labels, ListPtr,
  2089.         GTLV_Selected, (UWORD) ~0,
  2090.         TAG_DONE
  2091.     );
  2092.     return(ListPtr);
  2093. }
  2094.  
  2095. MODULE void writeiffgadgets(void)
  2096. {   // update the gadgets according to variables
  2097.  
  2098.     GT_SetGadgetAttrs
  2099.     (   CB61_CD,
  2100.         MainWindowPtr,
  2101.         NULL,
  2102.         GTCB_Checked, iff.cd,
  2103.         TAG_DONE
  2104.     );
  2105.     GT_SetGadgetAttrs
  2106.     (   CB61_RKM,
  2107.         MainWindowPtr,
  2108.         NULL,
  2109.         GTCB_Checked, iff.rkm,
  2110.         TAG_DONE
  2111.     );
  2112.     GT_SetGadgetAttrs
  2113.     (   CB61_Obsolete,
  2114.         MainWindowPtr,
  2115.         NULL,
  2116.         GTCB_Checked, iff.obsolete,
  2117.         TAG_DONE
  2118.     );
  2119.     GT_SetGadgetAttrs
  2120.     (   CB61_Private,
  2121.         MainWindowPtr,
  2122.         NULL,
  2123.         GTCB_Checked, iff.private,
  2124.         TAG_DONE
  2125.     );
  2126.     GT_SetGadgetAttrs
  2127.     (   CB61_Proposal,
  2128.         MainWindowPtr,
  2129.         NULL,
  2130.         GTCB_Checked, iff.proposal,
  2131.         TAG_DONE
  2132.     );
  2133.     GT_SetGadgetAttrs
  2134.     (   CB61_Reserved,
  2135.         MainWindowPtr,
  2136.         NULL,
  2137.         GTCB_Checked, iff.reserved,
  2138.         TAG_DONE
  2139.     );
  2140.     GT_SetGadgetAttrs
  2141.     (   CB61_Standard,
  2142.         MainWindowPtr,
  2143.         NULL,
  2144.         GTCB_Checked, iff.standard,
  2145.         TAG_DONE
  2146.     );
  2147.     GT_SetGadgetAttrs
  2148.     (   CB61_Unregistered,
  2149.         MainWindowPtr,
  2150.         NULL,
  2151.         GTCB_Checked, iff.unregistered,
  2152.         TAG_DONE
  2153.     );
  2154.     GT_SetGadgetAttrs
  2155.     (   ST61_FORMID,
  2156.         MainWindowPtr,
  2157.         NULL,
  2158.         GTST_String, queryform,
  2159.         TAG_DONE
  2160.     );
  2161.     chunkdesc("-");
  2162. }
  2163.